使用 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

参考文献

  1. 第 3 步:连接到 SQL 的概念验证使用 pyodbc
  2. 第一步:配置pyodbc开发环境Python 发展
  3. Step 2: Create a SQL database for pyodbc Python development
  4. Python on Azure

我能够重现您的问题。您正在使用为 SQL Server 2000 编写的非常旧的 "SQL Server" ODBC 驱动程序。TVP 是在 SQL Server 2008 中引入的。

所以,您收到错误是因为您正在使用的驱动程序不理解 TVP,因为它们在驱动程序存在时不存在 created.You 需要使用更现代的驱动程序版本,例如,"ODBC Driver 17 for SQL Server".