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

使用Python调用SQL存储过程报错:Previous SQL was not a query

问题:Python调用SQL存储过程报错"No results. Previous SQL was not a query"

已完成字符串doc_id转varbinary的处理,但调用SQL存储过程时出现如下错误:

Error executing stored procedure: No results. Previous SQL was not a query

Python代码

with pyodbc.connect(connection_string) as conn:
    with conn.cursor() as cursor:
        # Execute the SELECT query
        try:
            select_query = "SELECT TOP (1) * FROM [MDW].[MDW_F_PurchaseOrder_attaches] where Document_Id = 333631"
            cursor.execute(select_query)
            select_row = cursor.fetchone()

            # Add the SELECT query result to the response message
            response_message += " SELECT Query Result:\n"
            if select_row:
                response_message += f"{select_row}\n"
            else:
                response_message += " No data found in the SELECT query.\n"

        except Exception as e:
            logging.error(f"Error executing SELECT query: {e}")
            response_message += " Failed to execute SELECT query. Check logs for details.\n"

        # Call the stored procedure with parameters
        try:
            stored_procedure = "EXEC MDW.SP_GetDocument @Hash = ?, @Login = ?"
            cursor.execute(stored_procedure, doc_id_binary, user_email)
            rows = cursor.fetchall()

            # Format the results into a readable string
            response_message += " Stored Procedure Result:\n"
            if rows:
                for row in rows:
                    response_message += f"{row}\n"
            else:
                response_message += " No data found for the given parameters.\n"

        except Exception as e:
            logging.error(f"Error executing stored procedure: {e}")
            response_message += " Failed to execute stored procedure. Check logs for details.\n"

SQL存储过程代码

ALTER procedure [MDW].[SP_GetDocument] @Hash varbinary(20),@Login varchar(200)
as
set @Hash=isnull(@Hash  ,0x36ACEDC6177EA070E533521B02DF279BCBD4BC93)

select top 1  Source_Db,Document_Id,Displayname
into #docs
 from MDW.MDW_F_PurchaseOrder_attaches
 where Hash_Document=@Hash

 IF @@ROWCOUNT=0
  select Source_Db=null,Document_Id=null,Displayname=null,_Message='Document not found'
 Else
  select *, _message='OK' from #docs where Document_Id %10=1 
  union
  select Source_Db=null,Document_Id=null,Displayname=null,_Message='Not allowed'
  from #docs where Document_Id %10<>1 
GO

报错原因分析

存储过程中先执行的select ... into #docs是DDL操作,执行后会返回一个"受影响行数"的结果集(不属于查询结果),之后才是真正返回业务数据的select语句。pyodbc执行存储过程时会先获取这个DDL产生的结果集,此时直接调用fetchall()会因为当前结果集不是查询结果而触发报错。

解决方案

方案1:修改Python代码跳过非查询结果集

在调用存储过程后,先跳过DDL操作产生的非查询结果集,再获取真正的查询数据:

# Call the stored procedure with parameters
try:
    stored_procedure = "EXEC MDW.SP_GetDocument @Hash = ?, @Login = ?"
    cursor.execute(stored_procedure, doc_id_binary, user_email)
    
    # 跳过所有非查询结果集
    while cursor.nextset():
        pass
    
    rows = cursor.fetchall()

    # Format the results into a readable string
    response_message += " Stored Procedure Result:\n"
    if rows:
        for row in rows:
            response_message += f"{row}\n"
    else:
        response_message += " No data found for the given parameters.\n"

except Exception as e:
    logging.error(f"Error executing stored procedure: {e}")
    response_message += " Failed to execute stored procedure. Check logs for details.\n"

方案2:修改存储过程抑制非查询结果集

在存储过程开头添加SET NOCOUNT ON;,直接抑制DDL/DML操作返回的行数结果,从根源避免多结果集问题:

ALTER procedure [MDW].[SP_GetDocument] @Hash varbinary(20),@Login varchar(200)
as
SET NOCOUNT ON; -- 添加此行抑制非查询结果集
set @Hash=isnull(@Hash  ,0x36ACEDC6177EA070E533521B02DF279BCBD4BC93)

select top 1  Source_Db,Document_Id,Displayname
into #docs
 from MDW.MDW_F_PurchaseOrder_attaches
 where Hash_Document=@Hash

 IF @@ROWCOUNT=0
  select Source_Db=null,Document_Id=null,Displayname=null,_Message='Document not found'
 Else
  select *, _message='OK' from #docs where Document_Id %10=1 
  union
  select Source_Db=null,Document_Id=null,Displayname=null,_Message='Not allowed'
  from #docs where Document_Id %10<>1 
GO

添加SET NOCOUNT ON;后,原Python代码无需修改即可正常获取存储过程返回的查询结果。

额外优化建议

存储过程中的@Login参数未被使用,可考虑移除该参数或补充对应的权限校验逻辑,避免冗余参数存在。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.13 13:05:55