使用 pyodbc 将数据传递给接受 Table 值参数的存储过程
Passing data to a stored procedure that accepts Table Valued Parameter using pyodbc
正在尝试将数据发送到接受 Table 值参数的存储过程。出现以下错误:
[Error] ('HY004', '[HY004] [Microsoft][ODBC SQL Server Driver]Invalid SQL data type (0) (SQLBindParameter)')
我知道这是由于数据类型不匹配造成的——但如何纠正呢?
当我使用 SQL 服务器分析器时,我看到以下内容
exec sp_sproc_columns N'[MyTestTvp]',N'dbo',@ODBCVer=3
Python代码
import pandas as pd
import pyodbc
from pandas.plotting import scatter_matrix
import matplotlib.pyplot as plt
def main():
cnxn = pyodbc.connect("Driver={SQL Server};Server=dataserver;UID=UserName;PWD=Password@123;Database=MySQLServerDatabase;")
dfInput = pd.read_sql_query('exec dbo.usp_Temp_GetAllPatientBKs_ToEncrypt ?', cnxn, params=['None'] )
c01 = [1, 2, 3]
param_array = []
for i in range(3):
param_array.append([c01[i]])
try:
cursor = cnxn.cursor()
result_array = cursor.execute("EXEC dbo.[MyTestTvp] ?", [param_array]).fetchall()
cursor.commit() #very important to commit
except Exception as ex:
print("Failed to execute MyTestTvp")
print("Exception: [" + type(ex).__name__ + "]", ex.args)
if __name__== "__main__":
main()
SQL 服务器中的 TVP
CREATE TYPE dbo.[MyList] AS TABLE
(
[Id] INT NOT NULL
);
-- create stored procedure
CREATE PROCEDURE dbo.[MyTestTvp]
(
@tvp dbo.[MyList] READONLY
)
AS
BEGIN
SET NOCOUNT ON;
SELECT * FROM @tvp
END
更新
非常感谢戈德汤普森。根据 Gord Thompson 发布的答案,我更改了连接
cnxn = pyodbc.connect("Driver={ODBC Driver 13 for SQL Server};Server=dataserver.sandbox.rcoanalytics.com;UID=SimpleTest;PWD=SimpleTest@123;Database=RCO_DW;")
然后我得到以下错误:
Data source name not found and no default driver specified
参考pyodbc + MySQL + Windows: Data source name not found and no default driver specified
然后在系统 DSN 选项卡的 ODBC 数据源管理器中的服务器上安装驱动程序={SQL 服务器的 ODBC 驱动程序 13}
control panel>Systems and Security>Administrative Tools.>ODBC Data Sources
参考文献
我能够重现您的问题。您正在使用为 SQL Server 2000 编写的非常旧的 "SQL Server" ODBC 驱动程序。TVP 是在 SQL Server 2008 中引入的。
所以,您收到错误是因为您正在使用的驱动程序不理解 TVP,因为它们在驱动程序存在时不存在 created.You 需要使用更现代的驱动程序版本,例如,"ODBC Driver 17 for SQL Server".
正在尝试将数据发送到接受 Table 值参数的存储过程。出现以下错误:
[Error] ('HY004', '[HY004] [Microsoft][ODBC SQL Server Driver]Invalid SQL data type (0) (SQLBindParameter)')
我知道这是由于数据类型不匹配造成的——但如何纠正呢?
当我使用 SQL 服务器分析器时,我看到以下内容
exec sp_sproc_columns N'[MyTestTvp]',N'dbo',@ODBCVer=3
Python代码
import pandas as pd
import pyodbc
from pandas.plotting import scatter_matrix
import matplotlib.pyplot as plt
def main():
cnxn = pyodbc.connect("Driver={SQL Server};Server=dataserver;UID=UserName;PWD=Password@123;Database=MySQLServerDatabase;")
dfInput = pd.read_sql_query('exec dbo.usp_Temp_GetAllPatientBKs_ToEncrypt ?', cnxn, params=['None'] )
c01 = [1, 2, 3]
param_array = []
for i in range(3):
param_array.append([c01[i]])
try:
cursor = cnxn.cursor()
result_array = cursor.execute("EXEC dbo.[MyTestTvp] ?", [param_array]).fetchall()
cursor.commit() #very important to commit
except Exception as ex:
print("Failed to execute MyTestTvp")
print("Exception: [" + type(ex).__name__ + "]", ex.args)
if __name__== "__main__":
main()
SQL 服务器中的 TVP
CREATE TYPE dbo.[MyList] AS TABLE
(
[Id] INT NOT NULL
);
-- create stored procedure
CREATE PROCEDURE dbo.[MyTestTvp]
(
@tvp dbo.[MyList] READONLY
)
AS
BEGIN
SET NOCOUNT ON;
SELECT * FROM @tvp
END
更新
非常感谢戈德汤普森。根据 Gord Thompson 发布的答案,我更改了连接
cnxn = pyodbc.connect("Driver={ODBC Driver 13 for SQL Server};Server=dataserver.sandbox.rcoanalytics.com;UID=SimpleTest;PWD=SimpleTest@123;Database=RCO_DW;")
然后我得到以下错误:
Data source name not found and no default driver specified
参考pyodbc + MySQL + Windows: Data source name not found and no default driver specified
然后在系统 DSN 选项卡的 ODBC 数据源管理器中的服务器上安装驱动程序={SQL 服务器的 ODBC 驱动程序 13}
control panel>Systems and Security>Administrative Tools.>ODBC Data Sources
参考文献
我能够重现您的问题。您正在使用为 SQL Server 2000 编写的非常旧的 "SQL Server" ODBC 驱动程序。TVP 是在 SQL Server 2008 中引入的。
所以,您收到错误是因为您正在使用的驱动程序不理解 TVP,因为它们在驱动程序存在时不存在 created.You 需要使用更现代的驱动程序版本,例如,"ODBC Driver 17 for SQL Server".