3

我正在使用 pyodbc 对 Azure SQL 数据仓库运行 UPDATE 语句:

cursor.execute(
  "UPDATE dbo.test SET desc = ? WHERE id = ?", desc, id
)

当 desc 值很简单时,这可以正常工作。但是当 desc 的值比较复杂(文本较长)时,执行上面的会吐出如下错误:

pyodbc.ProgrammingError: ('42000', "[42000] [Microsoft][ODBC Driver 17 for SQL Server][SQL Server]104220;
Cannot find data type 'ntext'. (100000) (SQLExecDirectW)")

我认为逃避可以解决任何问题,但事实并非如此。任何想法/见解?

4

2 回答 2

2

你能试试这个:

cursor.execute(
  "UPDATE dbo.test SET desc = CAST(? AS NVARCHAR(MAX)) WHERE id = ?", desc, id
)

我猜 pyodbc 以某种方式将大字符串转换为ntext.

如果这没有帮助,请检查以下github 链接- 它可能会对您有所帮助,因为它解释了如果:

您正在使用将 nvarchar 视为 ntext 的旧 SQL Server (WDAC) 驱动程序,这就是您遇到问题的原因,因为 django-pyodbc-azure 中没有对 ntext 类型的引用

于 2019-09-13T05:15:25.630 回答
1

更新 - 2022-02-21:

ODBC Driver 18 for SQL Server 添加了一个LongAsMax连接字符串参数,因此我们可以告诉驱动程序将长类型映射为更现代的*(max)类型而不是旧TEXT/NTEXT/IMAGE类型。更多信息在这里


正如相关GitHub 问题中所建议的,解决方法是使用setinputsizes作为 ODBC 驱动程序的提示:

# test data
desc = ' '.join(['abcde' for x in range(2000)])

crsr.setinputsizes([(pyodbc.SQL_WVARCHAR, 0), (pyodbc.SQL_INTEGER,)])
crsr.execute("UPDATE ##test SET [desc]=? WHERE id=?", desc, id)

有驱动发送的效果

exec sp_prepare @p1 output,N'@P1 nvarchar(max),@P2 int',N'UPDATE ##test SET [desc]=@P1 WHERE id=@P2',1

代替

exec sp_prepare @p1 output,N'@P1 ntext,@P2 int',N'UPDATE ##test SET [desc]=@P1 WHERE id=@P2',1
于 2019-09-13T15:13:19.467 回答