使用pyodbc操作SQL Server表变量报错:No results. Previous SQL was not a query
问题原因
当执行包含INSERT(或UPDATE/DELETE)的多语句SQL时,SQL Server会先返回受影响的行数作为第一个结果集。pyodbc的游标默认停留在这个非查询的结果集上,此时调用fetchall()自然会报错——因为当前结果集不是查询返回的数据集。
而标量变量的场景里,DECLARE和SET语句不会产生任何结果集,游标直接定位到最后的SELECT结果,所以能正常获取数据。
解决方案
有两种可靠的解决方式:
方式一:添加SET NOCOUNT ON;抑制行数结果集
在SQL开头加上SET NOCOUNT ON;,让SQL Server不返回INSERT等操作的受影响行数,这样最后的SELECT结果就会成为唯一的结果集:
SQL_QUERY = """ SET NOCOUNT ON; DECLARE @MyTable TABLE (ID INT, Name NVARCHAR(255)); INSERT INTO @MyTable (ID, Name) VALUES (1, 'John'), (2, 'Jane'); SELECT * FROM @MyTable; """ cursor.execute(SQL_QUERY) records = cursor.fetchall() print(records)
方式二:手动跳过非查询结果集
如果无法修改SQL语句,可以调用cursor.nextset()跳过前面的受影响行数结果集,再获取查询数据:
SQL_QUERY = """ DECLARE @MyTable TABLE (ID INT, Name NVARCHAR(255)); INSERT INTO @MyTable (ID, Name) VALUES (1, 'John'), (2, 'Jane'); SELECT * FROM @MyTable; """ cursor.execute(SQL_QUERY) # 跳过INSERT操作返回的非查询结果集 cursor.nextset() records = cursor.fetchall() print(records)
内容的提问来源于stack exchange,提问作者zurich_ruby
相关产品推荐
相关产品推荐

