Я использую пакет odbc в R, и у меня есть база данных SQL Server с таблицей, в которой столбец Name
равен nvarchar(max)
, а столбец PublishStatus
-целое число.
Этот код не работает:
library(odbc)
library(DBI)
library(tidyverse)
con_string="Driver=ODBC Driver 11 for SQL Server;Server=myServer; Database=MyDatabase; trusted_connection=yes"
con=dbConnect(odbc::odbc(), .connection_string =con_string)
query="select * from MyTable"
result=NULL
result=dbSendQuery(con,query) %>% dbFetch
head(result)
Он просто выдает сообщение об ошибке
Ошибка в result_fetch (res @ ptr, n,...): nanodbc / nanodbc.cpp: 2890: 07009: [Microsoft] [ODBC Driver 11 для SQL Server] Индекс недопустимых дескрипторов
Если я попытаюсь выполнить запрос снова, я получу другое сообщение об ошибкеи, насколько я могу судить, невозможно восстановить без закрытия R и повторного открытия:
Ошибка: «выберите PublishStatus, имя из MyTable» nanodbc / nanodbc.cpp: 1587: HY000: [Microsoft][Драйвер ODBC 11 для SQL Server] Соединение занято результатами для другой команды
Поскольку оба odbc для R и R ужасно названы, в этом пакете сложно погуглить ошибки Google.В этом SO выясняется, что порядок столбцов имеет значение, и он требует, чтобы целые столбцы были указаны первыми в запросе.
Так что это работает
query="select PublishStatus,Name from MyTable"
result=NULL
result=dbSendQuery(con,query) %>% dbFetch
head(result)
, но это не так:
query="select Name,PublishStatus from MyTable"
result=NULL
result=dbSendQuery(con,query) %>% dbFetch
head(result)
, а запрос select *
- нет.
Так что мои вопросыявляются:
- Есть ли способ сделать это, чтобы я мог сделать
select *
запросов? - Когда я получаю ошибку
Invalid Descriptor Index
, есть ли способ восстановиться без перезапуска R?
Если нет, это выглядит как очень странный прерыватель сделки для этого пакета.
Редактировать : при использовании более старой библиотеки RODBC этот недостаток отсутствует даже при использовании того же драйвера ODBC.Это прекрасно работает с select * from
запросами и не заботится о порядке столбцов
library(RODBC)
con=odbcDriverConnect(ConnectionString_Hemonc)
result=sqlQuery(con,query,stringsAsFactors=FALSE)
close(con)
head(result)
. Ранее я отказался от RODBC, поскольку не может (на практике) записать данные вбаза данных, как я обнаружил здесь .
Похоже, что произошло, они построили odbc
для более быстрого чтения данных, и побочным эффектом этого является то, что теперь он очень требователен к порядку, в котором данныечитать.К сожалению, это разрушает мой вариант использования - я не могу просить людей, которые знают только базовый SQL, использовать инструмент, который рассматривает совершенно допустимый SQL как недопустимый.
Я думаю, это RODBC
для чтения данных, odbc
для записи данных.Yikes.
Edit 2 : я попытался ODBC Driver 13 for SQL Server
в строке подключения вместо ODBC Driver 11
, и это не решило проблему, но, по крайней мере, это было заметно быстрее.