You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Python调用MSSQL存储过程遇TypeError:Connection.execute()参数异常

问题描述

尝试用Python脚本调用MSSQL的存储过程Sp_Test向表中插入数据,存储过程代码如下:

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() got an unexpected keyword argument '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)
解决方案

1. 修正参数传递格式

SQLAlchemy的Connection.execute()方法不支持直接传入关键字参数,必须将参数作为第二个位置参数传入,可选择字典或列表格式:

字典传参(按名称匹配)

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

列表传参(按位置匹配)

params = [
    process_code,
    username,
    hostname,
    row_count,
    'Shared',
    None,
    None
]
with engine.connect() as conn:
    conn.execute(text("CALL Sp_Test(?, ?, ?, ?, ?, ?, ?, @NewBatchId OUT)"), params)

2. 补全存储过程的完整参数列表

你的存储过程定义了8个参数(含OUT参数),但最初调用只传入了5个,遗漏了@Postpone、@Deadline和OUT参数@NewBatchId。即使存储过程内部将前两个参数设为NULL,也需要显式传入对应值,否则会触发参数不匹配问题。

3. 获取OUT参数返回值(可选)

如果需要获取存储过程返回的@NewBatchId,可以通过声明变量并查询的方式实现:

from sqlalchemy import text

with engine.connect() as conn:
    new_batch_id = conn.execute(
        text("DECLARE @NewBatchId INT; EXEC Sp_Test :ProcessId, :CreatedByUserName, :CreatedByMachineName, :NumberOfDataRows, :DataSource, :Postpone, :Deadline, @NewBatchId OUT; SELECT @NewBatchId AS NewBatchId"),
        {
            'ProcessId': process_code,
            'CreatedByUserName': username,
            'CreatedByMachineName': hostname,
            'NumberOfDataRows': row_count,
            'DataSource': 'Shared',
            'Postpone': None,
            'Deadline': None
        }
    ).scalar()

print(f"生成的BatchId: {new_batch_id}")

内容的提问来源于stack exchange,提问作者Punya Munasinghe

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.23 14:41:19