MSSQL2008 – Pyodbc – 以前的SQL不是一个查询

我无法弄清楚下面的代码有什么问题,语法是好的(用SQL Management Studio检查),我有访问,因为我应该这样做..但由于某种原因,当我尝试创build一个表通过PyODBC然后停止工作。

import pyodbc def SQL(QUERY, target = '...', DB = '...'): cnxn = pyodbc.connect('DRIVER={SQL Server};SERVER=' + target + DB+';UID=user;PWD=pass') cursor = cnxn.cursor() cursor.execute(QUERY) cpn = [] for row in cursor: cpn.append(row) return cpn print SQL("CREATE TABLE dbo.Approvals (ID SMALLINT NOT NULL IDENTITY PRIMARY KEY, HostName char(120));") 

它失败:

 Traceback (most recent call last): File "test_sql.py", line 25, in <module> print SQL("CREATE TABLE dbo.Approvals (ID SMALLINT NOT NULL IDENTITY PRIMARY KEY, HostName char(120));") File "test_sql.py", line 20, in SQL for row in cursor: pyodbc.ProgrammingError: No results. Previous SQL was not a query. 

任何人有任何想法,为什么这是? 我安装了一个“SQL Server”驱动程序(它是默认的),在Windows 2008 SQL Server环境(非快速数据库)上运行Windows 7。

Solutions Collecting From Web of "MSSQL2008 – Pyodbc – 以前的SQL不是一个查询"

万一有些孤独的网络游民遇到这个问题,Torxed的解决方案对我来说并不适用。 但下面的工作对我来说。

我正在调用一个SP,它将一些值插入表中,然后返回一些数据。 只需将以下内容添加到SP:

 SET NOCOUNT ON 

它会工作得很好:)

Python代码:

  query = "exec dbo.get_process_id " + str(provider_id) + ", 0" cursor.execute(query) row = cursor.fetchone() process_id = row[0] 

SP:

 USE [DBNAME] GO SET ANSI_NULLS ON GO SET QUOTED_IDENTIFIER ON GO ALTER procedure [dbo].[GET_PROCESS_ID]( @PROVIDER_ID INT, @PROCESS_ID INT OUTPUT ) AS BEGIN SET NOCOUNT ON INSERT INTO processes(provider_id) values(@PROVIDER_ID) SET @PROCESS_ID= SCOPE_IDENTITY() SELECT @PROCESS_ID AS PROCESS_ID END 

首先:

如果您正在运行Windows SQL server 2008,请使用SQL软件安装中包含的“Native Client”(它随数据库和工具包一起安装,因此您需要从Microsoft安装SQL管理应用程序)

其次:在你的SQL连接语句中使用“Trusted_Connection = yes”

 cnxn = pyodbc.connect('DRIVER={SQL server Native Client 10.0};SERVER=serverAddress;DATABASE=my_db;Trusted_Connection=yes') 

这应该做的伎俩!

如果你的SQL不是存储过程。

在查询中使用'xyz!= NULL'会给出相同的错误,例如“pyodbc.ProgrammingError:No results。Previous SQL not a query”。

改为使用“不为空”。

我得到了这个,因为我正在重复使用我正在循环的游标:

 rows = cursor.execute(...) for row in rows: # run query that returns nothing cursor.execute(...) # next iteration of this loop will throw 'Previous SQL' error when it tries to fetch next row because we re-used the cursor with a query that returned nothing 

改用2个不同的游标

 rows = cursor1.execute(...) for row in rows: cursor2.execute(...) 

或者在再次使用之前获取第一个游标的所有结果:

改用2个不同的游标

 rows = cursor.execute(...) for row in list(rows): cursor.execute(...) 

正如其他的内容所述, SET NOCOUNT ON将处理存储过程中的额外结果集,但是其他的东西也可能导致额外的输出,NOCOUNT不会阻止(pyodbc将看作结果集),例如在调试后忘记删除打印语句您的存储过程。