【问题标题】:Convert an MS Access update query in SQL Server在 SQL Server 中转换 MS Access 更新查询
【发布时间】:2020-12-04 12:12:43
【问题描述】:

我目前正在构建一个基于以前的 MS Access 应用程序的闪亮应用程序。我需要在 SQL Server 中的每个 Shiny 应用程序按钮后面复制 MS Access 查询。在 R 中重用 MS Access 中的 SQL 语法的最佳方法是什么(即直接在 R 中复制粘贴 MS Access 查询)?

实际上,Access SQL 似乎与 SQL Server 语法略有不同,因此我不能简单地使用 DBI(dbGetQuery()dbExecute()dbSendQuery())或 dbplyr(sql())来实现。

这是一个在 R 中使用 MS Access SQL 语法的示例。(“100%”是故意留下的,因为表名包含该字符串。)

UPDATE [table1] 
INNER JOIN ([table2 100%] 
 INNER JOIN ([table3]
  INNER JOIN table4 
   ON ([table3].[col1] = table4.[col1]) 
   AND ([table3].col2 = table4.col2)) 
  
    ON ([table2 100%].[col1] = [table3].[col1]) 
    AND ([table2 100%].[col2] = [table3].[col2])) 

     ON [table1].col1 = [table3].col1 
SET [table2 100%].[col2] = [table3]![col2]
WHERE ((([table3].[colY])<>0) AND (([table3].[colZ])=True));

导致在 R 控制台中出现以下错误消息:

错误:nanodbc/nanodbc.cpp:1617:42000:[Microsoft][ODBC SQL Server Driver][SQL Server]关键字“INNER”附近的语法不正确。 [Microsoft][ODBC SQL Server Driver][SQL Server]'table3' 附近的语法不正确。 [Microsoft][ODBC SQL Server Driver][SQL Server]无法准备语句。

当我调整查询时,我还得到:“多部分标识符......无法在 Join 语句中绑定”。

我建立了我的连接:

con <- DBI::dbConnect(odbc::odbc(), driver = params.SQL.driver, 
    server = params.SQL.server, database = params.SQL.database, 
    encoding = params.SQL.encoding)

其中 params.SQL.server = "SQL Server"

【问题讨论】:

  • 第一条评论:“我不能简单地使用任一 DBI 来做到这一点”= 当我在该函数的语句部分复制粘贴 MS Access 查询时:DBI::dbExecute(conn = con, statement = my_query)。这会导致错误。第二条评论:是的,我正在尝试在 SQL Server 中转换 MS Access 更新查询。我天真地认为复制粘贴就可以了。但是 MS Access SQL 和 SQL server 的语法不同
  • @parfait 我通过 odbc 连接到 MS Access 以获取所需的表并将它们写入 SQL 服务器。我只连接过一次,现在我只连接到 SQL Server

标签: sql r ms-access dbplyr


【解决方案1】:

除了UPDATEE...FROM 翻译,考虑避免嵌套JOIN,因为MS Access 倾向于这样做。具体来说,将所有ON 子句移动到JOIN 子句之后,如果所有表都与INNER JOIN 结合,这应该可以工作。实际上,您甚至可以将WHERE 条件移动到ON

还要考虑表别名以提高速记性。最后,通常要更新的表列应该在FROM 子句中。此外,如果table1table4 不用于过滤,则它们是多余的。

UPDATE [t2]                                 -- USING ALIAS
SET [t2].[col2] = [t3].[col2]
FROM [table2 100%] t2                       -- MOVED DUE TO SET COLUMN REFERENCE

INNER JOIN [table3] t3
  ON  [t3].[col1] = [t2].[col1]
  AND [t3].[col2] = [t2].[col2] 
  AND [t3].[colY] <> 0
  AND [t3].[colZ] = 1                       -- NO True CONSTANT IN SQL SERVER

INNER JOIN [table1] t1
  ON  [t1].[col1] = [t3].[col1]   

INNER JOIN table4 t4
   ON  t4.[col1] = [t3].[col1]
   AND t4.[col2] = [t3].[col2]

【讨论】:

  • 谢谢,按照您的方式订购 INNER JOIN 是有效的。以后我也会用别名
【解决方案2】:

Access 有一个非常奇怪和非典型的 UPDATE 语法,它允许它同时更新多个表并合并数据(向表中添加行)。

SQL Server 有不同的语法,您需要明确说明要更新哪个表。

然而,重写很简单:

  • UPDATE 关键字之后列出您正在更新的表。

  • 将所有联接(包括该表)移至 FROM 子句。

  • 此外,SQL Server 中没有感叹号而不是点,但为了兼容性,我建议您在 Access 中也避免使用这些。

UPDATE [table1] 
SET [table2 100%].[col2] = [table3].[col2]
FROM [table1] 
INNER JOIN ([table2 100%] 
 INNER JOIN ([table3]
  INNER JOIN table4 
   ON ([table3].[col1] = table4.[col1]) 
   AND ([table3].col2 = table4.col2)) 
  
    ON ([table2 100%].[col1] = [table3].[col1]) 
    AND ([table2 100%].[col2] = [table3].[col2])) 

     ON [table1].col1 = [table3].col1 
WHERE ((([table3].[colY])<>0) AND (([table3].[colZ])=True));

【讨论】:

  • 感谢您的回答,这似乎更清楚一点。我刚刚尝试过,现在得到错误:无法绑定多部分标识符“[table2 100%].[col2]”。在这篇文章之后:radacad.com/…。我也应该为“AND”编写特定的内部连接吗?
  • @Cam11 关于多部分标识符的错误通常意味着您拼错了表名或列名。彻底检查您的姓名,表名中应允许使用百分号,但这可能会打扰您。
  • 这个多部分标识符错误可能是由于嵌套了JOINs。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-07-20
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多