简体   繁体   中英

Is there a way to return a Stored Procedure Return_Value to the python script executing it?

I am writing a python script that should update a log table and notify me of it. Part of this script is to execute a SQL Server stored procedure. I get an email telling me the status of the script as well as the status of the Stored procedure depending on the return value. But I can't seem to get my stored procedure to return the Return_Value. The script executes the stored procedure but receives no feedback.

I have tried using SQLAlchemy:

resulta = engine.execute(text(""" DECLARE @return int EXEC @return = [MYPROC] '{User}', '{Status}' 
                         SELECT 'RETURN' = @return """.format(User = curruser, Status = 'Pass')).execution_options(autocommit=True))

My resulta returns: <sqlalchemy.engine.cursor.LegacyCursorResult object at 0xXXXXXXXXXX>

I have also tried using cursors:

resultb = cur.execute(""" DECLARE @return int EXEC @return = [MYPROC] '{User}', '{Status}' 
                         SELECT 'RETURN' = @return """.format(User = curruser, Status = 'Pass'))

My resultb returns: NoneType object

I have also tried replacing the SELECT with a RETURN but that seems to cause more issues. Please help.

You certainly can do this using pyodbc Cursors. You need to know in advance how many result sets are returned by the stored procedure that you're executing so that the result set with the return code is where you expect.

The following example executes sp_helpdb with a @dbname parameter, which returns two result sets from the stored procedure itself and the third result set holds the return code...

import pyodbc

server = 'tcp:127.0.0.1,1433' 
database = 'master' 
username = 'sa' 
password = 'StrongPassw0rd' 

connStr = 'DRIVER={ODBC Driver 17 for SQL Server};SERVER='+server+';DATABASE='+database+';UID='+username+';PWD='+ password
cnxn = pyodbc.connect(connStr)
cursor = cnxn.cursor()

params = ( ('tempdb') )
result = cursor.execute("""
    declare @ReturnCode int;
    exec @ReturnCode = sp_helpdb @dbname = ?;
    select @ReturnCode as ReturnCode;
""", params)

# 1st result set from stored procedure...
databaseColumns = tuple([column[0] for column in result.description])
databaseRows = result.fetchall()
print(databaseColumns)
print(databaseRows)
print()

result.nextset()

# 2nd result set from stored procedure...
logicalFileColumns = tuple([column[0] for column in result.description])
logicalFileRows = result.fetchall()
print(logicalFileColumns)
print(logicalFileRows)
print()

result.nextset()

# 3rd result set for return code...
returnCodeColumns = tuple([column[0] for column in result.description])
returnCodeRows = result.fetchall()
print(returnCodeColumns)
print(returnCodeRows)
print()

That outputs the following to the console...

('name', 'db_size', 'owner', 'dbid', 'created', 'status', 'compatibility_level')
[
  ('tempdb', '     24.00 MB', 'sa', 2, 'Apr 29 2022', 'Status=ONLINE, Updateability=READ_WRITE, UserAccess=MULTI_USER, Recovery=SIMPLE, Version=904, Collation=SQL_Latin1_General_CP1_CI_AS, SQLSortOrder=52, IsAutoCreateStatistics, IsAutoUpdateStatistics', 150)
]

('name', 'fileid', 'filename', 'filegroup', 'size', 'maxsize', 'growth', 'usage')
[
  ('tempdev', 1, '/var/opt/mssql/data/tempdb.mdf', 'PRIMARY', '8192 KB', 'Unlimited', '65536 KB', 'data only'),
  ('templog', 2, '/var/opt/mssql/data/templog.ldf', None, '8192 KB', 'Unlimited', '65536 KB', 'log only'),
  ('tempdev2', 3, '/var/opt/mssql/data/tempdb2.ndf', 'PRIMARY', '8192 KB', 'Unlimited', '65536 KB', 'data only')
]

('ReturnCode',)
[(0, )]

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM