我正在运行一个python脚本,它连接到MSSQL数据库,运行一个存储过程,并应该根据存储过程的返回值采取一些行动。下面是代码。
'''
sql = """\
SET NOCOUNT ON
DECLARE @rv INT
EXEC @rv = [MY_DB].[dbo].[sp_Load_Actuals]
SELECT @rv
"""
...
conn = pyodbc.connect('Driver={ODBC Driver 13 for SQL Server};'
'Server=MY_SERVER;'
'Database=MY_DB;'
'Trusted_Connection=yes;')
conn.autocommit = True
cursor = conn.cursor()
cursor.execute(sql)
retv = cursor.fetchone()
...
在执行最后一条语句时,我捕捉到了 pyodbc.DatabaseError 异常的消息 "没有结果。前一个SQL不是查询"。 我看了这里所有的相关文章,但显然我还是做错了什么。
我错过了什么?
你必须调用 cursor.nextset()
来跳过任何被调用的存储过程输出的信息消息,因为NOCOUNT ON在这里是不够的。
但不幸的是 cursor
没有 .hasrows()
方法,所以你必须在一个循环中捕获异常。
例如
import pyodbc
sql = """\
SET NOCOUNT ON
DECLARE @rv INT
EXEC @rv = sp_executesql N'print ''informational message'''
SELECT @rv
"""
conn = pyodbc.connect('Driver={ODBC Driver 17 for SQL Server};'
'Server=localhost;'
'Database=tempdb;'
'Trusted_Connection=yes;')
conn.autocommit = True
cursor = conn.cursor()
cursor.execute(sql)
while True:
try:
retv = cursor.fetchone()
break
except pyodbc.ProgrammingError as e:
if "Previous SQL was not a query." in str(e):
if not cursor.nextset():
throw
print(retv)