问题描述
我目前正在构建基于以前的MS Access应用程序的Shiny应用程序。我需要在sql Server中的每个“闪亮”应用程序按钮后面复制MS Access查询。在R中的MS Access中重用sql语法的最佳方法是什么(即直接在R中复制并粘贴MS Access查询)?
实际上,Access sql似乎与sql Server语法略有不同,因此,我不能简单地使用DBI(dbGetQuery()
,dbExecute()
,dbSendQuery()
)或dbplyr({{ 1}})。
这里是R中使用MS Access sql语法的示例。(由于表名包含该字符串,因此故意保留“ 100%”。)
sql()
在R控制台中导致以下错误消息:
Erreur:nanodbc / nanodbc.cpp:1617:42000:[Microsoft] [ODBC sql Server驱动程序] [sql Server]关键字“ INNER”附近的语法不正确。 [Microsoft] [ODBC sql Server驱动程序] [sql Server]“ table3”附近的语法不正确。 [Microsoft] [ODBC sql Server驱动程序] [sql Server]声明无法准备。
当我调整查询时,我还得到:“多部分标识符…不能在Join语句中绑定”。
我与:
建立了联系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));
其中 params.sql.server =“ sql Server”
解决方法
除了UPDATEE...FROM
转换外,还应考虑避免JOIN
的嵌套,因为MS Access往往这样做。具体来说,将所有ON
子句移到JOIN
子句之后,这在所有表与INNER JOIN
组合在一起的情况下应该可以使用。实际上,您甚至可以将WHERE
个条件移至ON
。
还考虑使用表别名以简化操作。最后,通常要更新的表列应放在FROM
子句中。另外,如果table1
和table4
未用于过滤,则它们是多余的。
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]
,
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));