38

I'm have a stored procedure, code:

DECLARE @RC int 
DECLARE @id varchar(13) 
DECLARE @pw varchar(13) 
DECLARE @depart varchar(32) 
DECLARE @class varchar(12) 
DECLARE @name varchar(12) 
DECLARE @birthday varchar(10) 
DECLARE @grade int 
DECLARE @subgrade int 
SELECT @id = 'test' 
SELECT @pw = '12345' 
SELECT @depart = 'none' 
SELECT @class = 'GM' 
SELECT @name = 'name' 
SELECT @birthday = 'None' 
SELECT @grade = 3 
SELECT @subgrade = 2 
EXEC @RC = [my_database].[dbo].[my_table] @id, @pw, @depart, @class, @name, @birthday, @grade, @subgrade 
DECLARE @PrnLine nvarchar(4000) 
PRINT 'Stored Procedure: my_database.dbo.my_table' 
SELECT @PrnLine = ' Return Code = ' + CONVERT(nvarchar, @RC)

How i can make a raw sql query to create account using this procedure? I'm using flask and pyodbc.

7 Answers 7

37

From the pyodbc documentation

To call a stored procedure right now, pass the call to the execute method using either a format your database recognizes or using the ODBC call escape format. (The ODBC driver will then reformat the call for you to match the given database.)

For SQL Server you would use something like this:

# SQL Server format
cursor.execute("exec sp_dosomething(123, 'abc')")

# ODBC format
cursor.execute("{call sp_dosomething(123, 'abc')}")

So to call your procedure

id_ = 'test' 
pw = '12345' 
depart = 'none' 
class_ = 'GM' 
name = 'name' 
birthday = 'None' 
grade = 3 
subgrade = 2 

sql = 'exec [my_database].[dbo].[my_table](?, ?, ?, ?, ?, ?, ?, ?)'
values = (id_, pw, depart, class_, name, birthday, grade, subgrade)

cursor.execute(sql, (values))
Sign up to request clarification or add additional context in comments.

5 Comments

here a problem: sqlalchemy.exc.ProgrammingError: (ProgrammingError) ('42000', "[42000] [Microsoft][ODBC SQL Server Driver][SQL Server]Incorrect syntax near '@P1'. (102) (SQLExecDirectW)") 'exe my_procedure(?, ?, ?)' ('5215125', '125151', '31231')
That looks like a syntax error in the stored procedure. Is @P1 a part of the real one?
Thank you, sql = 'exec [my_database].[dbo].[my_table] ?, ?, ?, ?, ?, ?, ?, ?' working fine(without brackets).
Without brackets works if you don't have spaces in the names, if you have spaces you need the brackets.....
Hello everybody please, How to get the return value if my stored procedure has a SELECT IDENT_CURRENT('TABLE') as ID, I want to get the ID.
32

The accepted answer does not address the issue of capturing the return value from the stored procedure, which can be done like this:

id_ = 'test' 
pw = '12345' 
depart = 'none' 
class_ = 'GM' 
name = 'name' 
birthday = 'None' 
grade = 3 
subgrade = 2 

sql = """\
SET NOCOUNT ON;
DECLARE @RC int;
EXEC @RC = [my_database].[dbo].[my_sp] ?, ?, ?, ?, ?, ?, ?, ?;
SELECT @RC AS rc;
"""
values = (id_, pw, depart, class_, name, birthday, grade, subgrade)
cursor.execute(sql, values)
rc = cursor.fetchval()  # pyodbc convenience method similar to cursor.fetchone()[0]

6 Comments

this seems to cause SQL Server to recompile the query for every execution rather than reusing execution plans causing high compiles and recompiles
I tried your answer with a SP that INSERT records in a table. I used pyodbc. In that sql string, I had used sql=""" SET NOCOUNT ON; EXEC [schema].[sp_name] ?,?,?,?,?""" ; cur.execute( sql,values). The python code did not throw any error. But when I checked in the table, No data was inserted. Why so?
@pythondumb - Did you remember to call .commit()?
Yes I did. I used conn.commit()
@pythondumb - Then please ask a new question and include a minimal reproducible example.
|
18

Don't forget SET NOCOUNT ON in your stored procedure.

1 Comment

This actually helped us deal with a problem of SP not working. Still I don't see how this is a factor
8

Another flavour of Gord's answer is using OUTPUT and named parameters (to be defined within the Stored procedure) for clarity.

id_ = 'test' 
pw = '12345' 
depart = 'none' 
class_ = 'GM' 
name = 'name' 
birthday = 'None' 
grade = 3 
subgrade = 2 

sql = """\
DECLARE @RC int;
EXEC [my_database].[dbo].[my_sp] @RC OUTPUT, @id_=?, @pw=?, @depart=?, @class_=?, @name=?, @birthday=?, @grade=?, @subgrade=?;
SELECT @RC AS rc;
"""
values = (id_, pw, depart, class_, name, birthday, grade, subgrade)
cursor.execute(sql, values)
rc = cursor.fetchval()

Comments

4

After searching everywhere for this solution, i couldnt find a simplified version. All results seem to overcomplicate this that should be so easy to do. Heres my solution.

 import pyodbc
 import pandas as pd
 import datetime as d


  conn = pyodbc.connect('Driver=;'
                  'Server=;'
                  'Database=;'
                  'UID=;'
                  'PWD=;')


     # define parameters to be passed in and out

     quarter_date = d.date(year=2020, month=10, day=1)

     SQL = r'exec TERRITORIES_SP @quarterStart = ' + "'" + str(quarter_date) + "'"

     print(SQL)

     try:
         cursor = conn.cursor()
          cursor.execute(SQL)
          cursor.close()
          conn.commit()
    finally:
          conn.close()

3 Comments

By using dynamic SQL you are leaving yourself open to SQL injection vulnerabilities.
Thanks. What would be a better approach?
Something like sql = r'exec TERRITORIES_SP @quarterStart = ?' followed by cursor.execute(sql, str(quarter_date)). I'll admit that in this case the SQL injection risk is low, but it's still bad form to promote dynamic SQL as a "simplified" solution.
3

With a cursor initialized by your connection, the sp can be called directly as follow

sql = " exec your_SP @codemp = ?, @fecha = ? "
prm = (dict['param1'], dict['param2'])
cursor.execute(qry, params)

Comments

-6

For MSSQL the correct format is this:

SQL = 'exec sp_UpdateUserGoogleAuthenticated ''?'', ''?'''

Try running the Stored Procedure in MSSQL in the SQL Query window and it will fail every time with () surrounding the ? marks. If you escape the single quotes it will allow for variables with spaces in them.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.