我正在尝试通过使用 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)
如果有人能帮我解决这个问题,谢谢?
正如问题评论中提到的,用于调用返回 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}