从SQL Server存储过程检索输出参数

8qgya5xd  于 2022-11-28  发布在  SQL Server
关注(0)|答案(1)|浏览(175)

尝试运行具有输出参数的MS SQL存储过程。我已按照文档中的说明执行此操作,但当我运行代码时,出现以下错误:系统错误:〈class 'pyodbc.Error'〉返回了一个带有错误集的结果。
我的存储过程

CREATE PROCEDURE [dbo].[my_stored_procedure]
      @IN1          INT
      @IN2          INT
    , @OUT          INT OUTPUT
AS
BEGIN
    SET @OUT = @IN + 1  
END

myclass.py

z = sqlalchemy.sql.expression.outparam("ret_%d" % 0, type_=int)
  x = 1
  y = 2
  exec = self.context.\
      execute(text(f"EXEC my_stored_procedure :x, :y, :z OUTPUT"), {"x": x, "y": y, "z": z})
  result = exec.fetchall()

context.py

def execute(self, statement, args=None):     
        if not args:
            return self.session.execute(statement)
        else:
            return self.session.execute(statement, args)

有什么建议吗?有人能看出我做错了什么吗?

cbeh67ev

cbeh67ev1#

.outparam()是在SQLAlchemy 0.4中添加的,用于解决使用Oracle时的特定需求,并且实际上仅由该方言使用。正如本文当前的SQLAlchemy文档中所提到的,使用存储过程是更特定于数据库/方言的任务之一,因为不同的DBAPI层处理存储过程的方式存在显著差异。
对于SQL Server,pyodbc Wiki解释了如何执行here。好消息是,如果存储过程除了输出/返回值之外不返回结果集,则不需要使用原始DBAPI连接。
对于(已更正的)存储过程

CREATE PROCEDURE [dbo].[my_stored_procedure]
      @IN          INT
    , @OUT         INT OUTPUT
AS
BEGIN
    SET @OUT = @IN + 1  
END

您可以使用以下命令:

import sqlalchemy as sa

engine = sa.create_engine("mssql+pyodbc://scott:tiger^5HHH@mssql_199")

sql = """\
SET NOCOUNT ON;
DECLARE @out_param int;
EXEC dbo.my_stored_procedure @IN = :in_value, @OUT = @out_param OUTPUT;
SELECT @out_param AS the_output;
"""
with engine.begin() as conn:
    result = conn.execute(sa.text(sql), {"in_value": 1}).scalar()
    print(result)  # 2

相关问题