result_fetch(res@ptr, n)': nanodbc/nanodbc.cpp:2966: 07009: [Microsoft][SQL 服务器的 ODBC 驱动程序 13] 无效的描述符索引

result_fetch(res@ptr, n)': nanodbc/nanodbc.cpp:2966: 07009: [Microsoft][ODBC Driver 13 for SQL Server]Invalid Descriptor Index

我在使用 R 语言的 MSSQL 时遇到问题,类似于 R DBI ODBC error: nanodbc/nanodbc.cpp:3110: 07009: [Microsoft][ODBC Driver 13 for SQL Server]Invalid Descriptor Index ,但有点不同,或者我不明白。

我与 DB 有明显的联系,当我发送这样的内容时,我的 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")

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

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")

当我发送这个请求时 - 是错误的: "result_fetch(res@ptr, n)': nanodbc/nanodbc.cpp:2966: 07009: [Microsoft][ODBC Driver 13 for SQL Server]Invalid Descriptor Index"

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

我刚接触 R 语言,很抱歉,如果它太简单了

编辑:如果您的年龄在 odbc-1.3.0 或以上,请跳过此部分并转到下面的原始答案。 (或更新并获得收益。)

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

# 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

巨大 赞扬@detule(PR !415 的作者)和@Jim(HG 上的@jimhester ) 和@krlmlr(以及其他几个人)用于更新和维护 odbc.


odbc-1.3.0 及以上)

前面,列的顺序很重要

这是使用 Microsoft 自己的“ODBC 驱动程序”时长期存在的错误:在 ODBC 标准中,Microsoft 说(我认为是武断的,因为没有其他驱动程序或 DBMS 认为这是必要的)“长数据”必须都在查询的末尾。 “长数据”含糊不清,MS的页面上也写着“比如255个字符”,不知道是不是公司号。

不幸的是,只要您在自己的 SQL 服务器上使用 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

本例中,longstr的长度为-1表示“最大”;即使是 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

参考文献:

更新 ODBC 包的解决方案取决于您使用的 Microsoft ODBC 驱动程序。当我升级到 ODBC-1.3.3 时,问题又来了。将 SQL 服务器 (https://docs.microsoft.com/en-us/sql/connect/odbc/download-odbc-driver-for-sql-server?view=sql-server-ver15) 的 Microsoft ODBC 驱动程序升级到 Microsoft ODBC 驱动程序 17 解决了这个问题。因此,如果上述解决方案对您不起作用,请尝试升级您的驱动程序。