我试图在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()
最后一行导致以下异常:
ProgrammingError: No results. Previous SQL was not a query.
这可能是什么问题?
答案 0 :(得分:8)
这里发生了什么。存储过程包含几个步骤。当它从SQL Server Management工作室执行时,很容易看到每个步骤如何产生单独的消息,例如"(3 row(s) affected)"
,并且只有最后一步产生响应。
显然,当通过pyodbc
游标调用时,每个单独的步骤都会产生一个单独的resultset
,其中所有结果集,但最后一个结果集,不包含可以通过{{ 1}}。
因此,解决问题的一个选择是使用fetchall()
迭代这些结果集,直到找到产生结果的结果集,例如:
nextset()
如另一个答案中所提到的,更好的选项是使用while cursor.nextset(): # NB: This always skips the first resultset
try:
results = cursor.fetchall()
break
except pyodbc.ProgrammingError:
continue
指令,这似乎会阻止所有中间的空SET NOCOUNT ON;
结果集。该指令可以简单地添加到proc调用之前,例如:
(# rows affected)
答案 1 :(得分:2)
您可以将SET NOCOUNT ON添加到您的SP并尝试 如果你不能修改SP,首先执行这个语句x然后调用SP
答案 2 :(得分:0)
对于存储过程,不需要.fetchall()。我遇到了类似的问题,拿走了这个标签即可清除它。
答案 3 :(得分:0)
我遇到了同样的问题。 请记住在您存储的过程中使用“ SET NOCOUNT ON”。 另外,请检查您存储的过程中是否没有“打印”语句。