我无法弄清楚下面的代码有什么问题,语法是好的(用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。
万一有些孤独的网络游民遇到这个问题,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将看作结果集),例如在调试后忘记删除打印语句您的存储过程。