Я немного погуглил, но, возможно, я не ввел правильное магическое заклинание в поле поиска.
Кто-нибудь знает, как получить выходные параметры из хранимой процедуры в Python? Я использую pymssql для вызова хранимой процедуры и не уверен в правильном синтаксисе для возврата выходного параметра. Я не думаю, что могу использовать какие-либо другие модули db, так как я запускаю их из коробки Linux для подключения к базе данных mssql на MS Server.
import pymssql
con = pymssql.connect(host='xxxxx',user='xxxx',password='xxxxx',database='xxxxx')
cur = con.cursor()
query = "EXECUTE blah blah blah"
cur.execute(query)
con.commit()
con.close()






Я не эксперт по питону, но после краткого ознакомления с DB-API 2.0 я считаю, что вам следует использовать метод курсора callproc следующим образом:
cur.callproc('my_stored_proc', (first_param, second_param, an_out_param))
Тогда вы получите результат в виде возвращенного значения (параметра out) в переменной «an_out_param».
Попробуйте найти другой драйвер, более совместимый с DB-API 2.0. Начать здесь - wiki.python.org/moin/SQL_Server
Похоже, он охватывает большую часть того же, что и эта ссылка: ramblings.timgolden.me.uk/2007/09/26/… Ни один из бесплатных / oss, похоже, еще не поддерживает callproc или не работает в Linux. Возможно, мне нужно будет изучить решение для веб-сервисов.
Я думаю, что прочитал, что callproc в настоящее время не реализован для SQL Server, когда я немного погуглил по этому поводу.
Какая библиотека не реализует callproc (кроме pymssql)? Я только что проверил источник adodbapi, и, похоже, он реализован (я на самом деле не тестировал реализацию).
Будет ли работать adodbapi в Linux? Похоже, он работает только в Windows.
На всякий случай, если кто-то еще увидит этот ответ, вы должны передать callproc выходные параметры, обернутые следующим образом: pymssql.output (int, -1) Как описано здесь: github.com/pymssql/pymssql/blob/…
Вы также можете использовать SELECT вместо EXECUTE. EXECUTE - это (iirc), по сути, SELECT, который на самом деле ничего не извлекает (просто вызывает побочные эффекты).
Если вы заставляете свою процедуру создавать таблицу, вы можете использовать этот результат в качестве замены out params.
Так что вместо:
CREATE PROCEDURE Foo (@Bar INT OUT, @Baz INT OUT) AS
BEGIN
/* Stuff happens here */
RETURN 0
END
делать
CREATE PROCEDURE Foo (@Bar INT, @Baz INT) AS
BEGIN
/* Stuff happens here */
SELECT @Bar Bar, @Baz Baz
RETURN 0
END
Похоже, что каждая библиотека python dbapi, реализованная поверх freetds (pymssql, pyodbc и т. д.), Не сможет получить доступ к параметрам вывода при подключении к Microsoft SQL Server 7 SP3 и выше.
http://www.freetds.org/faq.html#ms.output.parameters
Этот ответ устарел, по крайней мере, для pymssql.
Если вы не можете или не хотите изменять исходную процедуру и иметь доступ к базе данных, вы можете написать простую процедуру-оболочку, вызываемую из python.
Например, если у вас есть такая хранимая процедура:
CREATE PROC GetNextNumber
@NextNumber int OUTPUT
AS
...
Вы можете написать такую обертку, которую легко вызвать из python:
CREATE PROC GetNextNumberWrap
AS
DECLARE @RNextNumber int
EXEC GetNextNumber @RNextNumber
SELECT @RNextNumber
GO
Тогда вы могли бы вызвать его из python так:
import pymssql
con = pymssql.connect(...)
cur = con.cursor()
cur.execute("EXEC GetNextNumberWrap")
next_num = cur.fetchone()[0]
Интересно, можете ли вы сделать это без вспомогательного sproc, просто с conn.execute ("DECLARE @RNextNumber int; EXEC GetNextNumber @RNextNumber out; SELECT @RNextNumber").
Мне удалось получить выходное значение из хранимой процедуры SQL с помощью Python. Мне не удалось найти хорошую помощь в получении выходных значений в Python. Я сам разобрался с синтаксисом Python, поэтому подозреваю, что это стоит опубликовать здесь:
import sys, string, os, shutil, arcgisscripting
from win32com.client import Dispatch
from adoconstants import *
#skip ahead to the important stuff
conn = Dispatch('ADODB.Connection')
conn.ConnectionString = "Provider=sqloledb.1; Data Source=NT38; Integrated Security = SSPI;database=UtilityTicket"
conn.Open()
#Target Procedure Example: EXEC TicketNumExists @ticketNum = 8386998, @exists output
Cmd = Dispatch('ADODB.Command')
Cmd.ActiveConnection = conn
Cmd.CommandType = adCmdStoredProc
Cmd.CommandText = "TicketNumExists"
Param1 = Cmd.CreateParameter('@ticketNum', adInteger, adParamInput)
Param1.Value = str(TicketNumber)
Param2 = Cmd.CreateParameter('@exists', adInteger, adParamOutput)
Cmd.Parameters.Append(Param1)
Cmd.Parameters.Append(Param2)
Cmd.Execute()
Answer = Cmd.Parameters('@exists').Value
pymssql v2.x предлагает ограниченную поддержку callproc. Он поддерживает параметры ВЫВОДА с использованием синтаксиса параметра pymssql.output(). Обратите внимание, однако, что параметры OUTPUT могут быть получены с помощью callproc только в том случае, если хранимая процедура нет также возвращает набор результатов. Этот вопрос обсуждается на GitHub здесь.
Учитывая хранимую процедуру T-SQL
CREATE PROCEDURE [dbo].[myDoubler]
@in int = 0,
@out int OUTPUT
AS
BEGIN
SET NOCOUNT ON;
SELECT @out = @in * 2;
END
код Python
import pymssql
conn = pymssql.connect(
host=r'localhost:49242',
database='myDb',
autocommit=True
)
crsr = conn.cursor()
sql = "dbo.myDoubler"
params = (3, pymssql.output(int, 0))
foo = crsr.callproc(sql, params)
print(foo)
conn.close()
производит следующий вывод
(3, 6)
Обратите внимание, что callproc возвращает кортеж параметров со значением параметра OUTPUT, присвоенным хранимой процедурой (в данном случае foo[1]).
Если хранимая процедура возвращает один или несколько наборов результатов, и также возвращает выходные параметры, нам нужно использовать анонимный блок кода для получения значений выходных параметров:
Хранимая процедура:
ALTER PROCEDURE [dbo].[myDoubler]
@in int = 0,
@out int OUTPUT
AS
BEGIN
SET NOCOUNT ON;
SELECT @out = @in * 2;
-- now let's return a result set, too
SELECT 'foo' AS thing UNION ALL SELECT 'bar' AS thing;
END
Код Python:
sql = """\
DECLARE @out_value INT;
EXEC dbo.myDoubler @in = %s, @out = @out_value OUTPUT;
SELECT @out_value AS out_value;
"""
params = (3,)
crsr.execute(sql, params)
rows = crsr.fetchall()
while rows:
print(rows)
if crsr.nextset():
rows = crsr.fetchall()
else:
rows = None
Результат:
[('foo',), ('bar',)]
[(6,)]
Можно попробовать переформатировать query:
import pypyodc
connstring = "DRIVER=SQL Server;"\
"SERVER=servername;"\
"PORT=1043;"\
"DATABASE=dbname;"\
"UID=user;"\
"PWD=pwd"
conn = pypyodbc.connect(connString)
cursor = conn.cursor()
query = "DECLARE @ivar INT \r\n" \
"DECLARE @svar VARCHAR(MAX) \r\n" \
"EXEC [procedure]" \
"@par1=?," \
"@par2=?," \
"@param1=@ivar OUTPUT," \
"@param2=@svar OUTPUT \r\n" \
"SELECT @ivar, @svar \r\n"
par1=0
par2=0
params=[par1, par2]
result = cursor.execute(query, params)
print result.fetchall()
Вот как я это сделал, главное - сначала объявить выходной параметр:
import cx_Oracle as Oracle
conn = Oracle.connect('xxxxxxxx')
cur = conn.cursor()
idd = cur.var(Oracle.NUMBER)
cur.execute('begin :idd := seq_inv_turnover_id.nextval; end;', (idd,))
print(idd.getvalue())
Ах ... к сожалению, у меня возникает эта ошибка. Похоже, что у pymssql нет callproc. AttributeError: экземпляр pymssqlCursor не имеет атрибута callproc