RODBCext:SQL 42000 402使用sqlExecute()

时间:2016-11-28 21:26:12

标签: sql-server r rodbc

我正在开发一个Shiny应用程序,用于更新SQLServer2008远程数据库中维护的条目。我一直在使用RODBC连接数据库,我试图通过RODBCext使用参数化查询来支持大量的信息更新。

我能够从运行R 3.2.3的Windows 7,RStudio中获取参数化查询,但出于某些原因,当我尝试从运行相同版本的R并连接的Linux机器运行相同的代码时使用相同版本的驱动程序,我收到以下错误:

Error in sqlExecute(Connection, data = dat) :
  42000 402 [Microsoft][ODBC Driver 13 for SQL Server][SQL Server]The data types char and text are incompatible in the equal to operator.
42000 8180 [Microsoft][ODBC Driver 13 for SQL Server][SQL Server]Statement(s) could not be prepared.
[RODBCext] Error: SQLExecute failed
In addition: Warning messages:
1: In sqlExecute(Connection, data = dat) :
  42000 402 [Microsoft][ODBC Driver 13 for SQL Server][SQL Server]The data types char and text are incompatible in the equal to operator.
2: In sqlExecute(Connection, data = dat) :
  42000 8180 [Microsoft][ODBC Driver 13 for SQL Server][SQL Server]Statement(s) could not be prepared.

以下是在我的Windows机器上正常工作的简单示例代码,但在linux机器上没有(我删除了连接字符串信息):

library(RODBCext)

Connection <- odbcDriverConnect(paste('Driver=ODBC Driver 13 for SQL Server', 
'Server=<Server IP>', 'Port=<Port>', 'Database=<Database>', 'UID = <UserID>', 
'PWD=<Password>', sep = ';'))

dat <- data.frame(Node_ID = "999", NodeGUID = "AF213171-201B-489B-B648-F7D289B735B1")

query <- "UPDATE dbo.Nodes SET Node_ID = ? WHERE NodeGUID = ?"

sqlPrepare(Connection, query)

sqlExecute(Connection, data = dat)

在此示例中,将使用列作为因子创建数据框。我已经尝试将列显式地转换为字符,因为这似乎适用于日期有问题的用户,但仍然会导致相同的SQL错误。我也尝试将Node_ID转换为数字以匹配SQL表,我得到了同样的错误。 SQL中Nodes表中的列定义为:

NodeGUID (PK, char(36), not null)
Node_ID (int, null)

我尝试通过提供sqlExecute的查询参数来组合sqlPrepare和sqlExecute调用,据我所知,这是一个微不足道的差异,它会导致相同的错误。

我怀疑驱动程序必须存在差异,以及它们如何实现sqlExecute()所做的任何SQL调用。我还怀疑sqlExecute()必须处理数据类型,因为无论列类型如何,我的结果都不会改变。

感谢您提供任何帮助!

1 个答案:

答案 0 :(得分:1)

感谢所有看过我问题的人。

我工作的一位SQL Server人员能够解决这个问题。他们建议在为sqlExecute()编写的SQL查询中显式地转换参数。这是有效的代码,注意我知道GUID将始终是36个字符,我相信我使用此查询的其余参数在转换为字符串时将小于1000:

my_query <- "UPDATE dbo.Nodes SET Node_ID = CAST(? As varchar(1000)) WHERE NodeGUID = CAST(? As varchar(36))"
sqlExecute(Connection, data = dat, query = my_query)

我猜测Windows的驱动程序以某种方式处理从text到varchar的转换,但linux驱动程序没有。

我希望这可以帮助其他人使用RODBCext。感谢Mateusz Zoltak和贡献者团队提供的精彩套餐!