MSSQL2008 - Pyodbc - 以前的 SQL 不是查询
我无法弄清楚以下代码有什么问题, 语法没问题(用 SQL Management Studio 检查),我可以按照我应该的方式访问,这样也可以工作..但由于某种原因,一旦我尝试通过 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 环境(不是 Express 数据库)上运行 Windows 7。
I can't figure out what's wrong with the following code,
The syntax IS ok (checked with SQL Management Studio), i have access as i should so that works too.. but for some reason as soon as i try to create a table via PyODBC then it stops working.
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));")
It fails with:
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.
Anyone have any idea to why this is?
I got a "SQL Server" driver installed (it's default), running Windows 7 against a Windows 2008 SQL Server environment (Not a express database).
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(11)
以防万一一些孤独的网络游牧者遇到这个问题,Torxed 的解决方案对我不起作用。但以下内容对我有用。
我正在调用一个 SP,它将一些值插入到表中,然后返回一些数据。只需将以下内容添加到 SP 中即可:
它会正常工作:)
Python 代码:
SP :
Just in case some lonely net nomad comes across this issue, the solution by Torxed didn't work for me. But the following worked for me.
I was calling an SP which inserts some values into a table and then returns some data back. Just add the following to the SP :
It'll work just fine :)
The Python code :
The SP :
使用脚本顶部的“SET NOCOUNT ON”值并不总是足以解决问题。
就我而言,还需要删除这一行:
数据库是 SQL Server 2012,
Python 3.7,
SQL Alchemy 1.3.8
希望这对某人有帮助。
Using the "SET NOCOUNT ON" value at the top of the script will not always be sufficient to solve the problem.
In my case, it was also necessary to remove this line:
Database was SQL Server 2012,
Python 3.7,
SQL Alchemy 1.3.8
Hope this helps somebody.
我得到这个是因为我重复使用了循环的游标:
使用 2 个不同的游标代替
,或者在再次使用第一个游标之前获取第一个游标的所有结果:
使用 2 个不同的游标代替
I got this because I was reusing a cursor that I was looping over:
Use 2 different cursors instead
or get all results of the first cursor before using it again:
Use 2 different cursors instead
正如 Travis 和其他人所提到的,其他事情也可能导致 SET NOCOUNT ON 无法阻止的额外输出。
我在程序开始时设置了 SET NOCOUNT ON,但在结果集中收到警告消息。
我在脚本开头设置了 ansi 警告,以删除错误消息。
希望这对某人有帮助。
As Travis and others have mentioned, other things can also cause extra output that SET NOCOUNT ON will not prevent.
I had SET NOCOUNT ON at the start of my procedure but was receiving warning messages in my results set.
I set ansi warnings off at the beginning of my script in order to remove the error messages.
Hopefully this helps someone.
正如其他人所介绍的,
SET NOCOUNT ON
将处理存储过程中的额外结果集,但是其他事情也可能导致 NOCOUNT 无法阻止的额外输出(并且 pyodbc 将视为结果集),例如忘记在调试存储过程后删除打印语句。As others covered,
SET NOCOUNT ON
will take care of extra resultsets inside a stored procedure, however other things can also cause extra output that NOCOUNT will not prevent (and pyodbc will see as a resultset) such as forgetting to remove a print statement after debugging your stored procedure.脚本中的每个语句都可以产生一些输出作为数据集或/和作为消息。
上面最后一行
是“messages”。如果我对此运行
cursor.fetchall()
,我将得到一个没有任何错误的结果。但是,如果我的查询是
insert .. into ..
或对不返回数据集的存储过程的调用,则对其执行fetchall()
会给我一个错误。有一种方法可以知道获取是否会给我
pyodbc.ProgrammingError
:cursor.description
具有数据集的所有字段定义它将是None
如果那里什么都没有。如果脚本中有多个语句,我可以使用
nextset()
迭代数据集。这是阅读完整响应的方法:要减少循环数量并最小化总体输出,请使用几乎所有其他答案中提到的 SET NOCOUNT ON 。如果 sql 语句没有生成数据集或消息,那么它会在输出中跳过,这就是您只需
cursor.fetchall()
而不是上面更长的脚本的方法Every statement in a script could produce some output either as a dataset or/and as a message.
produce
Last line above is "messages". If I run
cursor.fetchall()
on this I will get a result back without any errors.But if my query is an
insert .. into ..
or a call to stored procedure that does not return dataset, thenfetchall()
on it would give me an error.There is a way to know if fetching would give me
pyodbc.ProgrammingError
:cursor.description
has all the field definitions for your dataset It would beNone
if there is nothing there.If I have multiple statements in a script I can iterate over datasets with
nextset()
. Here is a way to read full response:To reduce number of loops and minimize the overall output, use
SET NOCOUNT ON
that is mentioned in almost all other answers. If sql statement has not produced dataset or message then it skipped in output and this is how you can do justcursor.fetchall()
instead of above much longer script如果您的存储过程调用 RAISERROR,pyodbc 可能会为该消息创建一个集合。
在 python 中,您需要跳过第一组,直到找到包含一些结果的组(请参阅 https://github.com/mkleehammer/pyodbc/issues/673#issuecomment-631206107 了解详细信息)。
If your stored procedure calls RAISERROR, pyodbc may create a set for that message.
In python, you need to skip the first sets until you find one containing some results (see https://github.com/mkleehammer/pyodbc/issues/673#issuecomment-631206107 for details).
我认为上述问题的根本原因可能与以下事实有关:当您执行例如不会返回结果的 DELETE 查询时,您会收到相同的错误消息。因此,如果您运行,
您会收到此错误,因为根据定义,DELETE 操作不会返回任何内容。尝试按照此处的建议捕获异常:如何检查结果集为空?
I think the root cause of the issue described above might be related with the fact that you receive the same error message when you execute for example a DELETE query which will not return a result. So if you run
you get this error, because a DELETE operation by definition does not return anything. Try to catch the exception as recommended here: How to check if a result set is empty?
如果您的 SQL 不是存储过程。
在查询中使用“xyz!= NULL”,将给出相同的错误,即“pyodbc.ProgrammingError:没有结果。以前的 SQL 不是查询。”
请改用“不为空”。
In case your SQL is not Stored Proc.
usage of 'xyz != NULL' in query, will give the same error i.e. "pyodbc.ProgrammingError: No results. Previous SQL was not a query."
Use 'is not null' instead.
首先:
如果您运行的是 Windows SQL Server 2008,请使用 SQL 软件安装中附带的“本机客户端”(它随数据库和工具包一起安装,因此您需要安装 Microsoft 的 SQL 管理应用程序) )
第二:
在 SQL 连接语句中使用 "Trusted_Connection=yes":
这应该可以解决问题!
First off:
if you're running a Windows SQL Server 2008, use the "Native Client" that is included with the installation of the SQL software (it gets installed with the database and Toolkits so you need to install the SQL Management applicaton from Microsoft)
Secondly:
Use "Trusted_Connection=yes" in your SQL connection statement:
This should do the trick!
我通过将使用数据库和sql查询分成两个执行语句解决了这个问题。
I have solved this problem by splitting the use database and sql query into two execute statements.