【问题标题】:Error "Previous SQL was not a query" in Python?Python中的错误“以前的SQL不是查询”?
【发布时间】:2016-12-23 14:02:07
【问题描述】:

我试图在 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.

这可能是什么问题?

【问题讨论】:

标签: python sql sql-server pyodbc


【解决方案1】:

这就是发生的事情。存储过程包含几个步骤。当它从 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()

【讨论】:

  • 当 sproc 主动将 nocount 设置为关闭时,调用 cursor.nextset() 对我有用,因此事先设置它不起作用。
  • 我无法让SET NOCOUNT ON 工作。 while 循环解决了我的问题,非常感谢。
【解决方案2】:

您能否将 SET NOCOUNT ON 添加到您的 SP 并尝试 如果不能修改SP,先执行这条语句x然后调用SP

【讨论】:

  • :- 我试过了,它在服务器上运行良好,但在 python 上却不行。
  • @jessica - 错误肯定看起来像缺少SET NOCOUNT ON; 在存储过程本身。您是否真的验证了SET NOCOUNT ON; 是存储过程中的第一个可执行语句?
【解决方案3】:

对于存储过程,您不需要 .fetchall()。我有一个类似的问题,拿掉那个标签就解决了。

【讨论】:

    【解决方案4】:

    我遇到了同样的问题。 请记住在存储过程中使用“SET NOCOUNT ON”。 另外,请检查您的存储过程中是否没有“打印”语句。

    【讨论】:

      【解决方案5】:

      我收到错误消息:“ProgrammingError:没有结果。以前的 SQL 不是查询。”在一些带有 openquery(不是存储过程)的 SQL 上。我在我的 openquery 之前添加了“SET NOCOUNT ON”并清除了错误。

      SQL 服务器 对 Oracle 的 OPENQUERY Python pyodbc

      【讨论】:

        【解决方案6】:

        对于未来的 Google 员工:我遇到了这个错误,当从 pyodbc 运行时,我的存储过程实际上甚至没有将数据插入到我想要的数据库表中。我的问题是执行后我没有关闭光标并提交。确保你这样做

        cursor.close()
        connection.commit()
        

        在运行 cursor.execute() 之后,如果你做的不仅仅是 SELECTs

        【讨论】:

          猜你喜欢
          • 2022-01-18
          • 2013-08-21
          • 2011-12-06
          • 1970-01-01
          • 1970-01-01
          • 2013-04-09
          • 1970-01-01
          • 1970-01-01
          • 2020-01-30
          相关资源
          最近更新 更多