Python中的"以前的SQL不是查询"错误?

6 python sql sql-server pyodbc

我试图在Python中调用存储过程,但它一直给我以下错误.该过程是用SQL Server 2008编写的,我使用PyODBC来调用方法并将参数传递给它.

import pyodbc
cnxn = pyodbc.connect('DRIVER={SQL Server};SERVER='+serveripaddr+';DATABASE='+database+';UID='+userid+';PWD='+password+'')
cursor = cnxn.cursor()
cursor.execute("{call p_GetTransactionsStats('KENYA', '41')}")
rows = cursor.fetchall()
Run Code Online (Sandbox Code Playgroud)

最后一行导致以下异常:

ProgrammingError: No results.  Previous SQL was not a query.
Run Code Online (Sandbox Code Playgroud)

这可能是什么问题?

KT.*_*KT. 13

这是发生了什么.存储过程包含几个步骤.当它从SQL Server Management工作室执行时,很容易看到每个步骤如何产生单独的消息,例如"(3 row(s) affected)",并且只有最后一步产生响应.

显然,当通过pyodbc游标调用时,每个单独的步骤都会产生一个单独的步骤resultset,其中所有结果集,但最后一个,不包含可以通过读取的数据fetchall().

因此,解决问题的一个选择是迭代这些结果集,nextset()直到找到产生结果的结果集,例如:

while cursor.nextset():   # NB: This always skips the first resultset
    try:
        results = cursor.fetchall()
        break
    except pyodbc.ProgrammingError:
        continue
Run Code Online (Sandbox Code Playgroud)

如在不同的答案中所提到的,更好的选择是使用该SET NOCOUNT ON;指令,该指令似乎阻止了所有中间的空(# rows affected)结果集.该指令可以简单地添加到proc调用之前,例如:

cursor.execute("set nocount on; exec MyStoredProc ?", some_parameter)
results = cursor.fetchall()
Run Code Online (Sandbox Code Playgroud)


Shi*_*ijo 5

你能不能给你的SP加上SET NOCOUNT ON试试,如果不能修改SP,先执行这个语句x然后调用SP