RODBCext: ошибка SQL 42000 402 при использовании sqlExecute()

Я работаю над приложением Shiny для обновления записей, хранящихся в удаленной базе данных SQLServer2008. Я подключаюсь к БД с помощью RODBC и пытаюсь использовать параметризованные запросы через RODBCext для поддержки массовых обновлений информации.

Я могу заставить параметризованные запросы работать с моей Windows 7, RStudio под управлением R 3.2.3, но по некоторым причинам, когда я пытаюсь запустить тот же код с Linux-машины, работающей с той же версией R и подключающейся к тому же версия драйвера, я получаю следующую ошибку:

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, и получаю ту же ошибку. Столбцы в таблице Nodes в SQL определяются как:

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

Я попытался объединить вызовы sqlPrepare и sqlExecute, предоставив аргумент запроса для sqlExecute, и, насколько я понимаю, это тривиальная разница, и она приводит к той же ошибке.

Я подозреваю, что должна быть разница в драйверах и в том, как они реализуют любые вызовы SQL, которые делает sqlExecute(). Я также подозреваю, что sqlExecute() должен обрабатывать типы данных, поскольку мои результаты не меняются независимо от типов столбцов.

Спасибо за любую помощь, которую вы можете предоставить!


person Nadir Sidi    schedule 28.11.2016    source источник
comment
Попробуйте другой драйвер, так как драйвер 13 может быть слишком новым для совместимости с RODBCext. Любопытно, штатный RODBC работает для драйвера?   -  person Parfait    schedule 29.11.2016
comment
Спасибо за ответ, Парфе. Я могу заставить все обычные функции RODBC работать с текущим драйвером.   -  person Nadir Sidi    schedule 29.11.2016


Ответы (1)


Спасибо всем, кто рассмотрел мой вопрос.

Один из специалистов по SQL Server на моей работе смог решить проблему. Они предложили явно приводить аргументы в SQL-запросе, написанном для sqlExecute(). Вот код, который работает, обратите внимание, я знаю, что 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 каким-то образом обрабатывает преобразование текста в varchar, а драйвер Linux - нет.

Я надеюсь, что это поможет другим, работающим с RODBCext. Спасибо Матеушу Золтаку и команде авторов за отличный пакет!

person Nadir Sidi    schedule 29.11.2016