简体   繁体   中英

pyodbc & MS SQL Server - “No results. Previous SQL was not a query.”

I am using pyodbc to retrieve data from a Microsoft SQL Server. The query is of the following form

SET NOCOUNT ON --Ignore count statements

CREATE TABLE mytable ( ... )

EXEC some_stored_procedure
INSERT mytable

--Perform some processing...

SELECT *
FROM mytable

The stored procedure performs some aggregation over values that contain NULLs such that warnings of the form Warning: Null value is eliminated by an aggregate or other SET operation. are issued. This results in pyodbc failing to retrieve data with the error message No results. Previous SQL was not a query. No results. Previous SQL was not a query.

I have tried to disable the warnings by setting SET ANSI_WARNINGS OFF . However, the query then fails with the error message 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. 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. .

Is it possible to

  • disable the warnings
  • or have pyodbc ignore the warnings?

Note that I do not have permissions to change the stored procedure.

Store the results of the query in a temporary table and execute the statement as two queries:

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

The first query does the heavy lifting and is of the form

--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

The second query retrieves the data and is of the form

SELECT * FROM #datastore

Thus, all warning messages are issued upon execution of the first query. They do not interfere with data retrieval during the execution of the second query.

I have had some luck mitigating this error by flipping ansi_warnings on and off just around the offending view or stored proc.

/* 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 */

This assumes that the entity that produces the aggregate warning doesn't also require warnings to be turned on. If it complains, it probably means that the entity itself has a portion of code like this that requires a toggle of the ansi_warnings (or a rewrite to eliminate the aggregation.)

One caviat is that I've found that this toggle still returns the "heterogeneous" warning if I try to run it as a cross-server query. Also, while debugging, it's pretty easy to get into a state where the ansi_warnings are flipped off when you don't realize it and you start getting heterogeneous errors for seemingly no reason. Just run the "set ANSI_WARNINGS on" line by itself to get yourself back into a good state.

Best thing is to add 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() 

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM