【发布时间】:2021-03-01 18:06:21
【问题描述】:
我知道我可以将 TVP 传递给存储过程(因为这是我之前在这里问过的问题)。我现在想知道这是否是我可以在 Python 中做的事情。我不断收到此错误。就是说有一个无效的类型,那么参数需要知道我传入的是什么类型吗?
pyodbc.ProgrammingError: ('42000', '[42000] [Microsoft][ODBC Driver 17 for SQL Server][SQL Server]列、参数或变量 #1:找不到只读数据类型。(2715) ( SQLExecDirectW); [42000] [Microsoft][ODBC Driver 17 for SQL Server][SQL Server]必须声明表变量“@P1”。(1087); [42000] [Microsoft][ODBC Driver 17 for SQL Server][ SQL Server]无法准备语句。(8180);[42000][Microsoft][ODBC Driver 17 for SQL Server][SQL Server]参数或变量“@P1”的数据类型无效。(2724) ')
from src.data.dbaccess import con
queryString2 = """
SET NOCOUNT ON
DECLARE @t As Table(
PersonName VARCHAR(50)
)
INSERT INTO @t
SELECT *
FROM ?
SELECT * FROM @t
"""
data = ([('Jim', ), ('Bob', )],)
with pyodbc.connect(con.conString) as testCon:
crsr = testCon.execute(queryString2, data)
for row in crsr:
print(row)
** 编辑澄清。在我去年的问题中,我问我是否可以将 TVP 传递给 SQL Server 存储过程。这一次,程序本身就是我的 Python 代码。这是我现在要解决的问题。
【问题讨论】:
-
不,这实际上是我去年提出的问题。这次的不同之处在于,与上次的 SQL Server 存储过程相比,我拥有 Python 中的全部代码。
-
哎呀,这很有趣 :-) 但是看看你当前的代码:你应该只通过 TVP 作为名称为
@t的参数,然后你可以直接从中选择。我完全不明白你为什么想要那个insert。还是 pyodbc 强制名称为@p1然后就使用它? -
我相当肯定你所描述的是不可能的。匿名代码块的问题在于它没有像存储过程那样声明输入和输出参数的机制,并且 SQL Server 要求将 TVP 声明为 READONLY 参数。 SQL Server 确实提供了一种声明临时存储过程(类似于临时表)的方法,但我只是尝试了一个快速测试,并且临时存储过程显然不能接受用户定义的类型作为参数。
-
@Charlieface 我认为他指的是一种使用 PYODBC 的方法。
标签: python sql-server pyodbc