result_fetch(res@ptr, n)': nanodbc/nanodbc.cpp:2966: 07009: [Microsoft][ODBC Driver 13 for SQL Server]描述符索引无效

dam*_*lit 4 sql r dbi mssql-jdbc

我在 R 语言中遇到 MSSQL 问题,类似于R DBI ODBC 错误:nanodbc/nanodbc.cpp:3110: 07009: [Microsoft][ODBC Driver 13 for SQL Server]Invalid Descriptor Index,但还有一点,或者我不知道不明白某事。

我与数据库有明显的联系,当我发送如下内容时,我的 SELECT 起作用:

third <- DBI::dbGetQuery(con, "SELECT TOP 1 
                         arr_delay_new,
                         fl_date,
                         carrier,
                         origin_city_name,
                         dest_city_name
                   FROM Flight_delays 
                   ORDER BY arr_delay_new DESC")
Run Code Online (Sandbox Code Playgroud)

问题出在列顺序上。我必须以其他顺序显示响应 - 像这样:

third <- DBI::dbGetQuery(con, "SELECT TOP 1 
                         carrier,
                         arr_delay_new,
                         fl_date,
                         origin_city_name,
                         dest_city_name
                   FROM Flight_delays 
                   ORDER BY arr_delay_new DESC")
Run Code Online (Sandbox Code Playgroud)

当我发送此请求时 - 出现错误:“result_fetch(res@ptr, n)': nanodbc/nanodbc.cpp:2966: 07009: [Microsoft][ODBC Driver 13 for SQL Server]无效描述符索引”

我如何设置这个或哪种解决方法可以帮助我更改订单?

我对 R 语言很陌生,很抱歉,如果它太简单了

r2e*_*ans 6

编辑:如果您年龄较大odbc-1.3.0,请跳过这部分并转到下面的原始答案。(或者更新并获得好处。)

从 开始odbc-1.3.1,底层代码围绕基本的 ODBC“功能”(bug)工作。通过更新,此特定错误不再指示列顺序问题(如果确实发生)。

编辑 2:确保您使用的是 Microsoft ODBC 驱动程序(操作系统级别)的最新版本,或者"ODBC Driver 17 for SQL Server""ODBC Driver 18 for SQL Server". 我不认为(但尚未证实)这对 17 或 18 内的颠覆敏感。

# con <- DBI::dbConnect(...)
DBI::dbExecute(con, "create table test (id int, longstr nvarchar(max), shortstr nvarchar(64))")
DBI::dbWriteTable(con, "test", data.frame(id=1, longstr="hello", shortstr="world"), create=FALSE, append=TRUE)
DBI::dbGetQuery(con, "select * from test")
#   id longstr shortstr
# 1  1   hello    world
Run Code Online (Sandbox Code Playgroud)

高度赞扬@detule(PR !415的作者)、@Jim(HG 上的@jimhester)和@krlmlr(以及其他几个)更新和维护odbc.


(适用于odbc-1.3.0及以上)

首先,列的顺序很重要

这是使用微软自己的“ODBC驱动程序”时长期存在的错误:在ODBC标准中,微软说(我认为是武断的,因为没有其他驱动程序或DBMS认为这是必要的)“长数据”必须全部位于查询结束。“长数据”是模糊的,甚至MS的页面上都写着“例如255个字符”,不确定这是否是确定的数字。

不幸的是,只要您为其自己的 SQL Server 使用 MS 的 ODBC 驱动程序,那么无论是 R、Python 还是 Access,它仍然会损坏。(事实上​​,他们并不认为它坏了。)

因此,解决方法是确定哪些列是“长”的,并确保它们是最后选择的列。

例如:

# con <- DBI::dbConnect(...)
DBI::dbExecute(con, "create table test (id int, longstr nvarchar(max), shortstr nvarchar(64))")
DBI::dbGetQuery(con, "select column_name, data_type, character_maximum_length from information_schema.columns where table_name='test'")
#   column_name data_type character_maximum_length
# 1          id       int                       NA
# 2     longstr  nvarchar                       -1
# 3    shortstr  nvarchar                       64
Run Code Online (Sandbox Code Playgroud)

在这种情况下,longstr的长度是-1,表示“max”;即使 255 也太大了。

DBI::dbWriteTable(con, "test", data.frame(id=1, longstr="hello", shortstr="world"), create=FALSE, append=TRUE)
DBI::dbGetQuery(con, "select * from test")
# Error in result_fetch(res@ptr, n) : 
#   nanodbc/nanodbc.cpp:2966: 07009: [Microsoft][ODBC Driver 17 for SQL Server]Invalid Descriptor Index 

### must reconnect
# con <- DBI::dbConnect(...)
DBI::dbGetQuery(con, "select id, shortstr, longstr from test")
#   id shortstr longstr
# 1  1    world   hello
Run Code Online (Sandbox Code Playgroud)

参考: