我试图在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.
这里有什么问题?
这就是发生的事情。存储过程包含多个步骤。从SQL Server Management Studio执行时,很容易看到每个步骤如何产生单独的消息,例如"(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
在不同答案中提到的一个更好的选择是使用SET NOCOUNT ON;
指令,该指令似乎可以防止所有中间,空的(# rows affected)
结果集。该指令可以简单地添加到PROC调用中,例如:
cursor.execute("set nocount on; exec MyStoredProc ?", some_parameter)
results = cursor.fetchall()
您可以将设置nocount添加到您的sp并尝试如果您无法修改SP,请首先执行此语句XAND,然后致电SP
对于将来的Googleers:我遇到了此错误,并且我的存储过程实际上甚至没有将数据插入我想要的数据库表中,从PYODBC运行时。我的问题是我没有关闭光标并在执行后提交。确保您做
cursor.close()
connection.commit()
运行Cursor.execute()之后,如果您做的不仅仅是选择
对于存储过程,您不需要.fetchall()。我也有一个类似的问题,然后将该标签清除了。
我遇到了同样的问题。切记在存储的Proc中使用"设置"。另外,请检查您存储的Proc。
我发现了错误:; quotingmingerror:没有结果。以前的SQL不是查询。"在某些SQL上,带有openquery(不是存储过程)。我添加了"设置"就在我的OpenQuery之前,并清除了错误。
SQL ServerOpenQuery到OraclePython pyodbc