类型错误:执行存储过程时,Connection.execute() 获得意外的关键字参数

问题描述 投票:0回答:1

我正在尝试通过使用 python 脚本执行存储过程来将数据插入 MSSQL 数据库表中。

这是我的存储过程 -

  SET ANSI_NULLS ON GO
  SET QUOTED_IDENTIFIER ON GO
  CREATE PROCEDURE [dbo].[Sp_Test] 
( 
   @ProcessId INT
  ,@CreatedByUserName VARCHAR(12)
  ,@CreatedByMachineName VARCHAR(12)
  --,@CreatedTime DATETIME
  ,@NumberOfDataRows INT  
  ,@DataSource VARCHAR(300)
  --,@RefId VARCHAR(8)
  ,@Postpone DATETIME2
  ,@Deadline DATETIME2
  ,@NewBatchId INT OUT 
) 
  AS  
  BEGIN    
  INSERT INTO Test(ProcessId, CreatedByUserName,
  CreatedByMachineName, CreatedTime, Postpone, Deadline,
  NumberOfDataRows, DataSource, RefId)   
  VALUES(
   @ProcessId,
   @CreatedByUserName, 
   @CreatedByMachineName, 
   GETDATE(), 
   NULL, 
   NULL,
   @NumberOfDataRows, 
   @DataSource, 
   CONVERT(VARCHAR(9),
   CRYPT_GEN_RANDOM(4), 2)
)
  SET @NewBatchId = SCOPE_IDENTITY();
  RETURN 0; 
END 
GO

这是我的Python代码片段。

with engine.connect() as conn:
                conn.execute(text("CALL Sp_Test(:ProcessId, :CreatedByUserName, :CreatedByMachineName, :NumberOfDataRows, :DataSource)"), ProcessId=process_code, CreatedByUserName=username,CreatedByMachineName=hostname,NumberOfDataRows=row_count,DataSource='Shared')

但是当我尝试运行我的脚本时,它给出以下错误。

TypeError:Connection.execute() 获得意外的关键字参数“ProcessId”

我也尝试将值作为字典传递。但错误是一样的。

params = {'ProcessId': process_code,'CreatedByUserName': username,'CreatedByMachineName': hostname,'NumberOfDataRows': row_count,'DataSource': 'Shared'} 
with engine.connect() as conn: 
conn.execute(text("CALL Sp_Test(:ProcessId, :CreatedByUserName, :CreatedByMachineName, :NumberOfDataRows, :DataSource)"),**params)

如果有人能帮我解决这个问题,谢谢?

python sql sql-server stored-procedures sqlalchemy
1个回答
0
投票

正如问题评论中提到的,用于调用返回 OUTPUT 变量和/或 RETURN 值的存储过程的 pyodbc 文档位于 here。但是,在您的情况下,您不需要诉诸原始 DBAPI 游标,因为您的 SP 不会返回结果集,因此您不需要调用 pyodbc 的

.nextset()
方法。您可以直接使用 SQLAlchemy,如下面的简化示例所示。

from sqlalchemy import create_engine, text

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

with engine.begin() as conn:
    sql = """\
        SET NOCOUNT ON;
        DECLARE @new_id int, @rtn int;
        EXEC @rtn = dbo.my_test_sp @ProcessId = :process_id, @NewBatchId = @new_id OUTPUT;
        SELECT @new_id AS new_batch_id, @rtn AS return_value;
        """
    result = conn.execute(text(sql), dict(process_id=123)).mappings().one()
    print(result)  # {'new_batch_id': 2, 'return_value': 0}
© www.soinside.com 2019 - 2024. All rights reserved.