You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Python通过pytds调用带表值参数的MSSQL存储过程报错求助

解决pytds调用MSSQL表值参数存储过程的类型识别错误

错误原因分析

你的代码存在几个关键问题导致类型识别失败:

  1. 表值参数行结构错误:rows参数需要接收多行数据的集合(即使只有一行也要用列表包裹),但你直接把单一行的内容(包含嵌套列表)传给了rows。
  2. 数据类型不匹配:SQL表值参数的列类型(如INT、DATETIME)需要和Python类型严格对应,你传入的字符串类型(如'0'、日期字符串)无法被pytds映射到正确的SQL类型。
  3. 嵌套表值参数未正确构造:JSON中的files数组对应SQL的嵌套表值类型,不能直接传Python列表,需要单独创建TableValuedParam对象。
  4. 未处理存储过程的输出参数:存储过程定义了@ReturnMessage输出参数,调用时必须传入OutputParam对象。

修正后的代码

首先确保导入必要模块:

from datetime import datetime
import pytds

然后编写正确的调用代码:

# 建立数据库连接
mydb = pytds.connect(server=server, user=username, password=password, database=database)
cursor = mydb.cursor()

# 1. 构造嵌套的文件表值参数(对应SQL中的FileDetailsType)
# 注意:日期字符串要转为datetime对象,匹配SQL的DATETIME类型
file_rows = [
    ('test1.txt', 'test2.txt', datetime.strptime('2023-02-28 23:25:03.000', '%Y-%m-%d %H:%M:%S.%f'))
]
files_tvp = pytds.TableValuedParam(type_name='dbo.FileDetailsType', rows=file_rows)

# 2. 构造主表值参数的行数据(对应SQL中的FileListType)
# 列顺序必须和FileListType的定义一致,类型严格匹配(如INT类型传整数)
main_tvp_rows = [
    (444, 0, '20230327XYZ', files_tvp)
]
main_tvp = pytds.TableValuedParam(type_name='dbo.FileListType', rows=main_tvp_rows)

# 3. 定义输出参数
return_message = pytds.OutputParam(str, size=1000)

# 4. 调用存储过程,参数顺序对应存储过程的输入、输出参数
cursor.callproc('test1', (main_tvp, return_message))

# 获取输出参数结果
print("返回消息:", return_message.value)

# 提交事务(如果涉及数据修改)
mydb.commit()

# 关闭资源
cursor.close()
mydb.close()

关键注意事项

  • 表值类型名称要带架构:必须指定完整的类型名(如dbo.FileListType),避免数据库找不到类型。
  • 严格匹配列顺序和类型:Python数据类型要和SQL表值参数的列类型一一对应:
    • SQL INT → Python int
    • SQL DATETIME → Python datetime对象
    • SQL VARCHAR → Python str
  • 嵌套表值参数需单独构造:如果表值参数包含嵌套的表值类型列,必须为该列单独创建TableValuedParam对象。
  • 更新pytds版本:确保使用最新版pytds,旧版本对表值参数的支持可能存在缺陷。

内容的提问来源于stack exchange,提问作者Ankit Singh

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.26 20:43:20