You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

PYODBC截断SQL Server FOR JSON查询结果的问题排查

解决PyODBC调用SQL Server存储过程返回JSON结果截断的问题

我之前也踩过这个坑!当用PyODBC调用返回JSON的SQL Server存储过程时,结果截断是个很常见的问题——毕竟SSMS里跑着正常,到Python里就出问题,确实让人头大。下面是我亲测有效的解决思路和办法:

1. 调整PyODBC的字符串长度限制

PyODBC默认对字符串类型的返回值有长度限制,这是导致JSON被截断的最常见原因。你可以通过两种方式解决:

  • 连接时设置全局参数:在创建数据库连接时,指定MAX_VARCHAR_SIZE=0(0表示不限制长度):
    import pyodbc
    
    conn_str = (
        "DRIVER={ODBC Driver 17 for SQL Server};"
        "SERVER=你的服务器地址;"
        "DATABASE=你的数据库;"
        "UID=用户名;"
        "PWD=密码"
    )
    conn = pyodbc.connect(conn_str, MAX_VARCHAR_SIZE=0)
    
  • 针对游标设置输出大小:在执行存储过程前,给游标设置对应类型的输出大小:
    cursor = conn.cursor()
    # SQL_WVARCHAR对应NVARCHAR类型,0表示不限制长度
    cursor.setoutputsize(0, pyodbc.SQL_WVARCHAR)
    cursor.execute("EXEC 你的存储过程名")
    

2. 优化存储过程的JSON返回逻辑

有时候SQL Server本身返回FOR JSON结果时,可能会因为默认的返回方式导致分段。你可以修改存储过程,把JSON结果先存入NVARCHAR(MAX)变量再输出,确保返回的是完整的单个字符串:

CREATE PROCEDURE 你的存储过程名
AS
BEGIN
    SET NOCOUNT ON;
    -- 先把JSON结果存入变量
    DECLARE @fullJson NVARCHAR(MAX);
    SET @fullJson = (SELECT * FROM 你的表 FOR JSON PATH);
    -- 输出完整的JSON字符串
    SELECT @fullJson AS JsonResult;
END

3. 正确读取Python中的结果

如果前面两步都做了,还是有截断的情况,可以尝试拼接所有返回行(极端情况下SQL Server可能会把长JSON拆分成多行返回):

cursor.execute("EXEC 你的存储过程名")
# 拼接所有行的内容
full_json = ''.join([row[0] for row in cursor.fetchall()])

为什么会出现这个问题?

简单来说,PyODBC默认不会自动处理NVARCHAR(MAX)这类大长度字符串,而SELECT...FOR JSON PATH返回的内容很容易超过它的默认长度限制。SSMS会自动处理大字符串的拼接,所以看起来正常,但PyODBC需要我们手动配置来支持完整读取。

内容的提问来源于stack exchange,提问作者Mark Sinkinson

火山引擎 最新活动