从Python调用的要插入的sqlserver存储过程并不总是存储数据,但仍会增加标识coutn

2024-06-16 11:36:46 发布

您现在位置:Python中文网/ 问答频道 /正文

我遇到了一个奇怪的不一致问题:使用存储过程的SQLServer插入。我通过pyodbc从Python调用一个存储过程,在表中插入多行时运行一个循环多次调用它。在

它似乎大部分时间都能正常工作,但过了一段时间它就会在循环中间停止工作。在这一点上,即使我试图通过代码调用它一次,它也不会插入任何内容。我在Python控制台中没有收到任何错误消息,实际上我返回了表的递增标识,就好像数据实际上被插入了一样,但是当我查看数据时,它不在那里。在

如果我从SQLServerManagementStudio中调用存储过程并传入数据,它将插入该存储过程并显示递增的标识号,就像插入了其他记录一样,即使它们不在数据库中。在

从Python调用存储过程的次数似乎达到了一定的限制,它就会停止工作。在

我要确保在循环完成插入和其他以相同方式编写并通过同一数据库连接发送的存储过程后断开连接仍能正常工作。在

我尝试过用sqlserver重新启动计算机,有时它会让我从Python调用存储过程多次,但最终也会停止工作。在

我想知道这是否与在循环中调用存储过程太快有关,但这并不能解释为什么在重新启动计算机后,它不允许从存储过程中进行更多的插入。在

我在网上做了很多搜索,但还没有找到类似的东西。在

以下是存储过程:

USE [Test_Results]
GO

SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO

CREATE PROCEDURE [dbo].[insertStepData]
@TestCaseDataId int,
@StepNumber nchar(10),
@StepDateTime nvarchar(50)
AS
SET NOCOUNT ON;
BEGIN TRANSACTION
DECLARE @newStepId int


INSERT INTO TestStepData (
    TestCaseDataId,
    StepNumber,
    StepDateTime
     )
    VALUES (
    @TestCaseDataId,
    @StepNumber,
    @StepDateTime

)
SET @newStepId = SCOPE_IDENTITY();


SELECT @newStepId
FROM TestStepData

COMMIT TRANSACTION

下面是我用来调用存储过程并获取id号的方法(“conn”是通过pyodbc的活动数据库连接):

^{pr2}$

这里是我传递要插入的存储过程的位置:

    ....
    for testStep in testStepData:  

        testStepId = self.CallSqlServerStoredProc(conn, "insertStepData", testCaseId, testStep["testStepNumber"], testStep["testStepDateTime"])

        conn.commit()
        time.sleep(1)

    ....

Tags: 数据数据库goon过程计算机connset
1条回答
网友
1楼 · 发布于 2024-06-16 11:36:46
SET @newStepId = SCOPE_IDENTITY();

SELECT @newStepId
FROM StepData

我觉得很可疑:

  1. ^{}返回大于intnumeric(38,0)。一段时间后可能会发生转换错误。更新:现在我们知道IDENTITY列是int,这不是问题(SCOPE_IDENTITY()返回当前范围内插入该列的最后一个值)。

  2. SELECT into variable doesn't guarantee its value if more that one record is returned。另外,我不明白重写已有的身份值背后的想法。除此之外,最后一条语句返回的值的数目等于该表中的行数这很可能是导致性能下降的原因。简言之,最后一句话不仅没用,而且是有害的。

第二条语句也会使这些语句行为不当:

^{pr2}$

由于该函数在一次内除了SELECT之外没有RETURN任何内容,因此该块实际上返回两个数据集:1)单个@newStepId值(来自EXEC,由SELECT @newStepId <...>生成);2)单个NULL(来自SELECT @ret)。fetchone()默认情况下读取第一个数据集,因此您不会注意到这一点,但无论如何,它对性能或正确性都不起作用。在

底线

将第二个语句替换为RETURN @newStepId。在

数据库中没有数据问题

我相信这是由RETURN在^{之前引起的。换个方向。在

在最初的形式中,我相信它是由长时间工作SELECT和/或{a3}引起的。在

相关问题 更多 >