Проблема с временной таблицей RODBC при подключении к MS SQL Server

Я запускаю R в Unix и использую пакет RODBC для подключения к серверу MS SQL. Я могу выполнить запрос, который возвращает результаты с пакетом, но если я использую временную таблицу где-то в своем SQL-запросе, мне возвращается пустая строка. Посмотрев в Интернете, я думаю, что проблема может заключаться в том, что пакет RODBC был написан, предполагая, что конечный пользователь пишет на стандартном SQL (в отличие от MS SQL). Я предоставил приведенный ниже код в качестве примера.

Интересно, что проблемы временной таблицы не существует, если я использую пакет RJDBC. Однако пакет RJDBC мучительно медленный при импорте даже 80 000 строк (10 столбцов) и часто зависает, так что это тоже не вариант. Кто-нибудь еще столкнулся с этой проблемой? Если есть альтернативные решения, о которых я не подумал, я хотел бы их услышать.

Кажется, я не один с этой проблемой, возможно, это R-Bug? http://r.789695.n4.nabble.com/RODBC-results-from-stored-procedure-td897462.html

Спасибо

Вот пример R:

library(RODBC)
ch <- odbcConnect(insert your server info here)
qry4 <- "create table #tempTable(
    Test int
)
insert into #tempTable
select 2

select * from #tempTable
drop table #tempTable
"
df4 <- sqlQuery(ch, qry4)

person rlh2    schedule 20.01.2011    source источник


Ответы (2)


Драйвер RODBC, по-видимому, считает, что когда SQL Server возвращает какое-либо количество строк, весь оператор завершен. Поэтому вам нужно установить nocount в начале вашего оператора или хранимой процедуры, которая вызывается.

set nocount on

Это позволило мне использовать хранимую процедуру, которая использовала временную таблицу в R.

person ChrisGheen    schedule 11.07.2012
comment
Это невероятно. Большое спасибо за это ChrisGheen. - person Moderat; 17.07.2015
comment
Это мне очень помогло - я могу использовать длительные сценарии с временными таблицами, вставками, удалениями и т. д., пока не получу последний запуск оператора select. Я использую это для DBI/ODBC с R. - person surpavan; 22.06.2018
comment
Мне не помогает?! - person cs0815; 16.07.2019

Проблема, похоже, в вашем синтаксисе SQL, а не в чем-то, что связано с R или пакетом RODBC. Я почти уверен, что вам нужно разделить операторы SQL с помощью команды go, чтобы гарантировать, что первый оператор завершится выполнением раньше второго, третьего и так далее. В качестве альтернативы вы можете разбить их на четыре разных утверждения, как я сделал ниже. Это работает на моей машине:

library(RODBC)
ch <- odbcConnect("details")

qry1 <- "create table #temptable (test int)"
qry2 <- "insert into #temptable(test) values(2)"
qry3 <- "select * from #temptable"
qry4 <- "drop table #temptable"

sqlQuery(ch, qry1)
sqlQuery(ch, qry2)
doesItWork <- sqlQuery(ch, qry3)
sqlQuery(ch, qry4)

И вывод

> doesItWork
  test
1    2

ИЗМЕНИТЬ

Превращение всех ваших запросов в объект списка и повторение их может избавить вас от написания кода в будущем. Например:

queryList <- list(qry1, qry2, qry3, qry4)
sqlOutput <- lapply(queryList, function(x) sqlQuery(ch, x))

Это создаст некоторые посторонние выходные данные, которые могут вас не волновать, но интересующие вас результаты можно получить с помощью sqlOutput[[3]], где 3 представляет интересующий запрос.

person Chase    schedule 20.01.2011
comment
Во-первых, спасибо за помощь, ваш метод работает и для меня. Что касается помещения моего запроса в одну строку, я не уверен, что разделение операторов с помощью команды go работает. Может ли это быть связано с тем, что я использую Transact SQL? - person rlh2; 20.01.2011
comment
@Bob - я недостаточно знаю о различных разновидностях SQL или о том, как интерфейс R для SQL принципиально отличается от обычного интерфейса, чтобы понять, почему он будет вести себя по-другому. Я предполагаю, что если вы выделите весь свой запрос выше и запустите его через студию управления, он будет работать нормально? Предполагая, что вам нужны отдельные запросы в R, чтобы заставить его работать, вы можете превратить их все в список и использовать lapply(). Я обновлю ответ, чтобы отразить этот метод. - person Chase; 20.01.2011
comment
@Bob Кстати, я думаю, что drop table не нужен, потому что вы создаете временную таблицу, поэтому она исчезнет, ​​когда вы закроете соединение. - person Marek; 20.01.2011
comment
С другой стороны, я думаю, это объясняет, почему хранимые процедуры, создающие временные таблицы и управляющие ими, не работают с RODBC. - person rlh2; 20.01.2011