Использование хранимых процедур SQL Server из Python (pyodbc)

У меня есть хранимая процедура, код:

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)

Как я могу сделать необработанный sql-запрос для создания учетной записи с помощью этой процедуры? Я использую флягу и pyodbc.

5 ответов


С документация pyodbc

чтобы вызвать хранимую процедуру прямо сейчас, передайте вызов методу execute, используя формат, который распознает ваша база данных, или используя формат побега вызова ODBC. (Драйвер ODBC затем переформатирует вызов для вас, чтобы соответствовать данной базе данных.)

для SQL Server вы бы использовали что-то вроде этого:

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

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

так назвать вашу процедуру

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

принятый ответ не решает проблему захвата возвращаемого значения из хранимой процедуры, что можно сделать следующим образом:

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

sql = """\
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]

Не забудьте установить NOCOUNT в вашей хранимой процедуре.


другой вкус ответа горда-использование выходных и именованных параметров (которые будут определены в хранимой процедуре) для ясности.

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

для MSSQL правильный формат:

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

попробуйте запустить хранимую процедуру в MSSQL в окне SQL-запроса, и она будет терпеть неудачу каждый раз, когда () окружает ? символика. Если вы избегаете одинарных кавычек, это позволит использовать переменные с пробелами в них.