Python通过Pyodbc调用存储过程无法获取输出报错如何解决
错误原因
你遇到的ProgrammingError: No results. Previous SQL was not a query报错,是因为执行存储过程的时候,SQL Server会先返回存储过程内部操作的受影响行数消息(没有对应查询结果),游标默认停在这个空结果集上,此时直接调用fetchval()就会触发错误,因为当前位置没有可返回的查询结果。
解决方案
方法1:SQL脚本新增SET NOCOUNT ON(最推荐)
关闭存储过程执行过程中返回的受影响行数消息,让最后的SELECT成为第一个也是唯一的结果集,同时修正你取值的代码逻辑:
import pyodbc import math import requests import pandas as pd cnx = pyodbc.connect('DRIVER={SQL Server};SERVER=xxxx;DATABASE=xxxx;UID=xxxxx;PWD=Minonja') SQL_send_data=""" SET NOCOUNT ON -- 新增这一行即可 DECLARE @messageStatus nvarchar(200) SELECT @messageStatus = N'@messageStatus' EXEC [cvm].[CVMSendSms_sp] @userId = N'PT180209.1100.628362', @codeSms = 79, @messageStatus = @messageStatus OUTPUT, @date = '', @amount = N'0' SELECT convert(varchar,@messageStatus) as reponse """ cursor = cnx.cursor() cursor.execute(SQL_send_data) res = cursor.fetchval() # 把返回值存到变量中 print(res) # 直接打印结果,不要打印cursor对象 cnx.commit() cursor.close()
方法2:遍历跳过空结果集
如果不想修改SQL脚本,可以主动跳转游标到有数据的结果集:
cursor.execute(SQL_send_data) # 循环跳过无数据的空结果集 while cursor.description is None: cursor.nextset() res = cursor.fetchval() print(res)
额外优化建议
不要直接把参数硬编码在SQL字符串中,用pyodbc的参数绑定能力避免SQL注入风险,参考写法:
params = ( 'PT180209.1100.628362', 79, '', '0' ) SQL_send_data=""" SET NOCOUNT ON DECLARE @messageStatus nvarchar(200) EXEC [cvm].[CVMSendSms_sp] @userId = ?, @codeSms = ?, @messageStatus = @messageStatus OUTPUT, @date = ?, @amount = ? SELECT convert(varchar,@messageStatus) as reponse """ cursor.execute(SQL_send_data, params)
内容的提问来源于stack exchange,提问作者Minonja Nandraina Razakasoa
相关产品推荐
相关产品推荐

