简体   繁体   English

Python中的存储过程如何获取output参数?

[英]How do you get output parameters from a stored procedure in Python?

I've googled around a bit, but maybe I didn't put the correct magik incantation into the search box.我用谷歌搜索了一下,但也许我没有在搜索框中输入正确的魔法咒语。

Does anyone know how to get output parameters from a stored procedure in Python?有谁知道如何从Python中的存储过程获取output参数? I'm using pymssql to call a stored procedure, and I'm not sure of the correct syntax to get the output parameter back.我正在使用 pymssql 调用存储过程,但不确定返回 output 参数的正确语法。 I don't think I can use any other db modules since I'm running this from a Linux box to connect to a mssql database on a MS Server.我不认为我可以使用任何其他数据库模块,因为我从 Linux 框运行它以连接到 MS 服务器上的 mssql 数据库。

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

I'm not a python expert but after a brief perusing of the DB-API 2.0 I believe you should use the "callproc" method of the cursor like this: 我不是python专家,但经过对DB-API 2.0的简要介绍后,我相信你应该使用游标的“callproc”方法,如下所示:

cur.callproc('my_stored_proc', (first_param, second_param, an_out_param))

Then you'll have the result in the returned value (of the out param) in the "an_out_param" variable. 然后你将得到“an_out_param”变量中返回值(out param)的结果。

If you cannot or don't want to modify the original procedure and have access to the database you can write a simple wrapper procedure that is callable from python. 如果您不能或不想修改原始过程并且可以访问数据库,则可以编写一个可从python调用的简单包装程序。

For example, if you have a stored procedure like: 例如,如果您有一个存储过程,如:

CREATE PROC GetNextNumber
   @NextNumber int OUTPUT
AS
...

You could write a wrapper like so which is easily callable from python: 你可以编写一个像这样的包装器,它可以从python中轻松调用:

CREATE PROC GetNextNumberWrap
AS
    DECLARE @RNextNumber int
    EXEC GetNextNumber @RNextNumber
    SELECT @RNextNumber
GO

Then you could call it from python like so: 然后你可以像这样从python中调用它:

import pymssql
con = pymssql.connect(...)
cur = con.cursor()
cur.execute("EXEC GetNextNumberWrap")
next_num = cur.fetchone()[0]

I was able to get an output value from a SQL stored procedure using Python. 我能够使用Python从SQL存储过程中获取输出值。 I could not find good help getting the output values in Python. 我找不到很好的帮助在Python中获取输出值。 I figured out the Python syntax myself, so I suspect this is worth posting here: 我自己想出了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

If you make your procedure produce a table, you can use that result as a substitute for out params. 如果你让你的程序产生一个表,你可以使用该结果代替out params。

So instead of: 所以代替:

CREATE PROCEDURE Foo (@Bar INT OUT, @Baz INT OUT) AS
BEGIN
   /* Stuff happens here */
   RETURN 0
END

do

CREATE PROCEDURE Foo (@Bar INT, @Baz INT) AS
BEGIN
   /* Stuff happens here */
   SELECT @Bar Bar, @Baz Baz
   RETURN 0
END

It looks like every python dbapi library implemented on top of freetds (pymssql, pyodbc, etc) will not be able to access output parameters when connecting to Microsoft SQL Server 7 SP3 and higher. 看起来在连接到Microsoft SQL Server 7 SP3及更高版本时,在freetds(pymssql,pyodbc等)之上实现的每个python dbapi库都将无法访问输出参数。

http://www.freetds.org/faq.html#ms.output.parameters http://www.freetds.org/faq.html#ms.output.parameters

You might also look at using SELECT rather than EXECUTE. 您可能还会考虑使用SELECT而不是EXECUTE。 EXECUTE is (iirc) basically a SELECT that doesn't actually fetch anything (, just makes side-effects happen). EXECUTE是(iirc)基本上是一个实际上不会获取任何内容的SELECT(只会产生副作用)。

2016 update (callproc support in pymssql 2.x) 2016更新(pymssql 2.x中的callproc支持)

pymssql v2.x offers limited support for callproc . pymssql V2.X提供了有限的支持callproc It supports OUTPUT parameters using the pymssql.output() parameter syntax. 它使用pymssql.output()参数语法支持OUTPUT参数。 Note, however, that OUTPUT parameters can only be retrieved with callproc if the stored procedure does not also return a result set. 但是请注意,该输出参数只能与检索callproc如果存储过程还返回结果集。 That issue is discussed on GitHub here . 这个问题在GitHub上讨论

For stored procedures that do not return a result set 对于不返回结果集的存储过程

Given the T-SQL stored procedure 给定T-SQL存储过程

CREATE PROCEDURE [dbo].[myDoubler] 
    @in int = 0, 
    @out int OUTPUT
AS
BEGIN
    SET NOCOUNT ON;
    SELECT @out = @in * 2;
END

the Python code 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()

produces the following output 产生以下输出

(3, 6)

Notice that callproc returns the parameter tuple with the OUTPUT parameter value assigned by the stored procedure ( foo[1] in this case). 请注意, callproc返回参数元组,其中包含由存储过程指定的OUTPUT参数值(在本例中为foo[1] )。

For stored procedures that return a result set 对于返回结果集的存储过程

If the stored procedure returns one or more result sets and also returns output parameters, we need to use an anonymous code block to retrieve the output parameter value(s): 如果存储过程返回一个或多个结果集并且还返回输出参数,我们需要使用匿名代码块来检索输出参数值:

Stored Procedure: 存储过程:

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 code: 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

Result: 结果:

[('foo',), ('bar',)]
[(6,)]

You can try to reformat query : 您可以尝试重新格式化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()

[1] https://amybughunter.wordpress.com/tag/pypyodbc/ [1] https://amybughunter.wordpress.com/tag/pypyodbc/

Here's how I did it, the key is to declare output parameter first: 这是我如何做到的,关键是首先声明输出参数:

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

I use pyodbc and then convert the pyodbc rows object to a list.我使用 pyodbc,然后将 pyodbc 行 object 转换为列表。 Most of the answers show a query declaring variables as part of the query.大多数答案显示查询声明变量作为查询的一部分。 But I would think you declare your variables as part of the sp, thus eliminating an unnecessary step in python. Then, in python, all you have to do is pass the parameters to fill in those variables.但我认为您将变量声明为 sp 的一部分,从而消除了 python 中不必要的步骤。然后,在 python 中,您所要做的就是传递参数以填充这些变量。

Here is the function I use to convert the pyodbc rows object to a usable list (of lists) (note that I have noticed pyodbc sometimes adds trailing spaces, so I account for that which works well for me):这是我用来将 pyodbc 行 object 转换为可用列表(列表)的 function(请注意,我注意到 pyodbc 有时会添加尾随空格,因此我考虑了对我来说效果很好的那个):

def convert_pyodbc(pyodbc_lst):
'''Converts pyodbc rows into usable list of lists (each sql row is a list),
   then examines each list for list elements that are strings,
   removes trailing spaces, and returns a usable list.'''
usable_lst = []
for row in pyodbc_lst:
    e = [elem for elem in row]
    usable_lst.append(e)
for i in range(0,len(usable_lst[0])):
    for lst_elem in usable_lst:
        if isinstance(lst_elem[i],str):
            lst_elem[i] = lst_elem[i].rstrip()
return usable_lst

Now if I need to run a stored procedure from python that returns a results set, I simply use:现在,如果我需要从 python 运行一个返回结果集的存储过程,我只需使用:

strtdate = '2022-02-21'
stpdate = '2022-02-22'

conn = mssql_conn('MYDB')
cursor = conn.cursor()

qry = cursor.execute(f"EXEC mystoredprocedure_using_dates 
'{strtdate}','{stpdate}' ")
results = convert_pyodbc(qry.fetchall())

cursor.close()
conn.close()

And sample results which I then take and write to a spreadsheet or w/e:以及样本结果,然后我将其写入电子表格或 w/e:

[[datetime.date(2022, 2, 21), '723521', 'A Team Line 1', 40, 9], 
[datetime.date(2022, 2, 21), '723522', 'A Team Line 2', 15, 10], 
[datetime.date(2022, 2, 21), '723523', 'A Team Line 3', 1, 5], 
[datetime.date(2022, 2, 21), '723686', 'B Team Line 1', 39, 27], 
[datetime.date(2022, 2, 21), '723687', 'B Team Line 2', 12, 14]]

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 如何从Python调用Windows .exe文件,输入参数并获取文件输出? - How do you call a windows .exe file from Python, enter parameters, and get a file output? 如何从 Python 池中获取控制台 output? - How do you get console output from Python pool? 如何调用python中带参数的存储过程? - How to call the stored procedure with parameters in python? Python:执行带参数的存储过程 - Python: Execute Stored Procedure with Parameters 如何传递日期参数以在 python pandas 中执行 sql 存储过程 - How to pass date parameters to execute sql stored procedure in python pandas 如何在python中使用这么多参数调用SQL Server存储过程? - How to call SQL Server stored procedure with so many parameters in python? 如何使用 Python 中的参数正确执行 MSSQL 存储过程 - How correctly execute a MSSQL stored procedure with parameters in Python 如何在python代码中使用带有参数的存储过程 - how can I use stored procedure with parameters in python code 使用 python 脚本中的游标输出参数调用 oracle 存储过程 - Call oracle stored procedure with cursor output parameter from python script 你如何在python中获得“matlab风格”函数输出 - How do you get “matlab style” function output in python
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM