Reputation: 779
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.
Upvotes: 37
Views: 133577
Reputation: 123429
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]
Upvotes: 30
Reputation: 61
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()
Upvotes: 5
Reputation: 57
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)
Upvotes: 3
Reputation: 359
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()
Upvotes: 8
Reputation: 1
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.
Upvotes: -6
Reputation: 20719
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))
Upvotes: 36