当TVP数据第一行为None时出现“无效SQL数据类型”错误
我在用pyodbc启动SQL Server数据库中的存储过程时遇到了一个错误,这个存储过程使用了表值参数(TVP),而且有一列的值是None。
[HY004] [Microsoft][ODBC Driver 18 for SQL Server]无效的SQL数据类型 (0) (SQLBindParameter)
有没有办法告诉pyodbc这列的具体数据类型,还是说我必须放弃使用表值参数(TVP)?
这是我正在尝试的:
cursor.execute("{CALL dbo.stored_procedure (?, ?)}", (None, tvp_data))
第一个变量我不在乎,第二个是我的表值参数(TVP)。只要在TVP的某一列中没有None,所有操作都正常,但如果有None,我就会遇到这个错误。
1 个回答
1
这是一个已知的问题,关于参数元数据发现的限制,具体讨论可以在GitHub上找到,链接在这里和这里。解决这个问题的方法有:
选项1:对你的TVP数据进行排序,确保第一行没有None
值。
选项2:在一个匿名代码块中使用OPENJSON()
,并将你的TVP数据作为JSON字符串传递。
tvp_data = [(1, None), (2, "Bravo")]
tvp_json = [dict(zip(["id", "txt"], row)) for row in tvp_data]
sql = """\
SET NOCOUNT ON;
DECLARE @tvp dbo.issue_1229_table_type;
INSERT INTO @tvp (id, txt)
SELECT id, txt FROM OPENJSON(?)
WITH (
id int '$.id',
txt nvarchar(50) '$.txt'
);
EXEC issue_1229_sp @tvp
"""
results = crsr.execute(sql, json.dumps(tvp_json, default=str)).fetchall()
print(results)
# [(1, None), (2, 'Bravo')]
(这个例子是我自己在GitHub评论中复制的,链接在这里。)