是否可以将值从PYODBC传递到SQL Server的表类型参数



我创建了一个测试类型,作为一个包含以下列的表:

CREATE TYPE [dbo].[TestType] AS TABLE
(
[TestField] [varchar](10) NULL,
[TestField2] [int] NULL
)

然后,我创建了一个存储过程,将该表类型作为参数。

CREATE PROCEDURE TestTypeProcedure (@tt TestType READONLY)
AS
SELECT *
FROM @tt;

我的目标是能够传递类似列表列表的内容作为表类型的参数。这可能吗?

myList = [['Hello!', 1], ['Goodbye!', 2]]
....
cursor.execute('{{Call {TestTypeProcedure} ({?})}}', myList)

pyodbc。编程错误:("SQL包含1个参数标记,但提供了2个参数","HY000"(

您得到这个错误是因为表值参数是可迭代的列表(最好是元组(。。。

my_tvp = [('Hello!', 1), ('Goodbye!', 2)]
print(f"my_tvp contains {len(my_tvp)} row(s)")
# my_tvp contains 2 row(s)

如果您将其直接传递给.execute(),则每一行都被解释为一个参数值:

sql = "{CALL TestTypeProcedure (?)}"
params = my_tvp
print(f"calling SP with {len(params)} parameter value(s)")
# calling SP with 2 parameter value(s)
crsr.execute(sql, params)  # error

因此,您需要将tvp封装在元组中,使其成为单个参数值

sql = "{CALL TestTypeProcedure (?)}"
params = (my_tvp, )  # tuple containing a single tvp "object"
print(f"calling SP with {len(params)} parameter value(s)")
# calling SP with 1 parameter value(s)
crsr.execute(sql, params)  # no error

Python:3.7.4和pyodbc:4.0.26中支持表值参数(TVP(。

有一个公开的反馈声称(我没有测试它(,您必须在SQL Server端使用模式dbo 创建类型

您可以在以下GitHub反馈中阅读更多信息:https://github.com/mkleehammer/pyodbc/issues/595

更新:您可以在此处关注Microsoft"入门"文档:https://learn.microsoft.com/en-us/sql/connect/python/pyodbc/python-sql-driver-pyodbc?view=sql-服务器-ver15

最新更新