4

我正在使用 pyodbc 从 Microsoft SQL Server 检索数据。查询格式如下

SET NOCOUNT ON --Ignore count statements

CREATE TABLE mytable ( ... )

EXEC some_stored_procedure
INSERT mytable

--Perform some processing...

SELECT *
FROM mytable

存储过程对包含NULLs发出表单警告的值执行一些聚合Warning: Null value is eliminated by an aggregate or other SET operation.。这导致 pyodbc 无法使用错误消息检索数据No results. Previous SQL was not a query.

我试图通过设置来禁用警告SET ANSI_WARNINGS OFF。但是,查询随后会失败并显示错误消息Heterogeneous queries require the ANSI_NULLS and ANSI_WARNINGS options to be set for the connection. This ensures consistent query semantics. Enable these options and then reissue your query.

是否有可能

  • 禁用警告
  • 还是让 pyodbc 忽略警告?

请注意,我没有更改存储过程的权限。

4

3 回答 3

4

将查询结果存储在临时表中,并将语句作为两个查询执行:

with pyodbc.connect(connection_string) as connection:
    connection.execute(query1)            #Do the work
    result = connection.execute(query2)   #Select the data
    data = result.fetchall()              #Retrieve the data

第一个查询完成繁重的工作,其形式为

--Do some work and execute complicated queries that issue warning messages

--Store the results in a temporary table
SELECT some, column, names
INTO #datastore
FROM some_table

第二个查询检索数据,其形式为

SELECT * FROM #datastore

因此,在执行第一个查询时发出所有警告消息。它们不会在执行第二个查询期间干扰数据检索。

于 2013-04-17T08:30:12.350 回答
3

我通过在有问题的视图或存储过程周围打开和关闭 ansi_warnings 来减轻这个错误。

/* vw_someView aggregates away some nulls and presents warnings that blow up pyodbc */
set ANSI_WARNINGS off
select *
into #my_temp
from vw_someView
set ANSI_WARNINGS on

/* rest of query follows */

这假定产生聚合警告的实体也不需要打开警告。如果它抱怨,这可能意味着实体本身有一部分这样的代码需要切换 ansi_warnings(或重写以消除聚合。)

一个问题是,如果我尝试将其作为跨服务器查询运行,我发现此切换仍会返回“异构”警告。此外,在调试时,很容易进入 ansi_warnings 在您没有意识到的情况下被关闭的状态,并且您似乎无缘无故地开始出现异构错误。只需单独运行“set ANSI_WARNINGS on”行,即可让自己恢复到良好状态。

于 2019-02-26T14:44:34.127 回答
0

最好的办法是添加 try: except: block

sql="sp_help stored_procedure;"
print(">>>>>executing {}".format(sql))
next_cursor=cursor.execute(sql)
while next_cursor:
try:
    row = cursor.fetchone()
    while row:
        print(row)
        row = cursor.fetchone()
except Exception as my_ex:
    print("stored procedure returning non-row {}".format(my_ex))
next_cursor=cursor.nextset() 
于 2020-10-08T06:21:41.930 回答