Can python cursor.execute accept multiple queries in one go?

Question:

Can the cursor.execute call below execute multiple SQL queries in one go?

cursor.execute("use testdb;CREATE USER MyLogin")

I don’t have python setup yet but want to know if above form is supported by cursor.execute?

import pyodbc 
# Some other example server values are
# server = 'localhostsqlexpress' # for a named instance
# server = 'myserver,port' # to specify an alternate port
server = 'tcp:myserver.database.windows.net' 
database = 'mydb' 
username = 'myusername' 
password = 'mypassword' 
cnxn = pyodbc.connect('DRIVER={ODBC Driver 17 for SQL Server};SERVER='+server+';DATABASE='+database+';UID='+username+';PWD='+ password)
cursor = cnxn.cursor()
#Sample select query
cursor.execute("SELECT @@version;") 
row = cursor.fetchone() 
while row: 
    print(row[0])
    row = cursor.fetchone()
Asked By: Test

||

Answers:

Yes, it is possible.

operation = 'SELECT 1; INSERT INTO t1 VALUES (); SELECT 2'
for result in cursor.execute(operation, multi=True):

But it is not a comprehensive solution. For example, in queries with two selections, you have problems.

Consider that two types of answers must be fetch all in the cursor!

So the best solution is to break the query to sub queries and do your work step by step.
for example :

s = "USE some_db; SELECT * FROM some_table;"
s = filter(None, s.split(';'))

for i in s:
    cur.execute(i.strip() + ';')
Answered By: user9613901

in the pyodbc documentation should give you the example your looking for. more over in the GitHub wiki: https://github.com/mkleehammer/pyodbc/wiki/Objects#cursors

you can see an example here:

cnxn   = pyodbc.connect(...)
cursor = cnxn.cursor()

cursor.execute("""
               select user_id, last_logon
                 from users
                where last_logon > ?
                  and user_type <> 'admin'
               """, twoweeks)

rows = cursor.fetchall()

for row in rows:
    print('user %s logged on at %s' % (row.user_id, row.last_logon))

from this example and exploring the code, I would say your next step is testing a multi cursor.execute("<your_sql_Querie>").

if this test works, maybe try and create a CLASS then create instances of that class for each query you want to run.

This would be the basic evolution of a developers effort of reproducing documentation…hope this helps you 🙂

Answered By: BlackFox

Multiple SQL statements in a single string is often referred to as an "anonymous code block".

There is nothing in pyodbc (or pypyodbc) to prevent you from passing a string containing an anonymous code block to the Cursor.execute() method. They simply pass the string to the ODBC Driver Manager (DM) which in turn passes it to the ODBC Driver.

However, not all ODBC drivers accept anonymous code blocks by default. Some databases default to allowing only a single SQL statement per .execute() to protect us from SQL injection issues.

For example, MySQL/Connector ODBC defaults MULTI_STATEMENTS to 0 (off) so if you want to run an anonymous code block you will have to include MULTI_STATEMENTS=1 in your connection string.

Note also that changing the current database by including a USE … statement in an anonymous code block can sometimes cause problems because the database context changes in the middle of a transaction. It is often better to execute a USE … statement by itself and then continue executing other SQL statements.

Answered By: Gord Thompson

Yes, you can results for multiple queries by using the nextset() method…

query = "select * from Table1; select * from Table2"
cursor = connection.cursor()
cursor.execute(query)

table1 = cursor.fetchall()

cursor.nextset()

table2 = cursor.fetchall()

The code explains it… cursors return result "sets", which you can move between using the nextset() method.

Answered By: Scurrae
Categories: questions Tags: , ,
Answers are sorted by their score. The answer accepted by the question owner as the best is marked with
at the top-right corner.