Sql server 过程从不插入某些行-SQL Server

Sql server 过程从不插入某些行-SQL Server,sql-server,stored-procedures,transactions,insert,deadlock,Sql Server,Stored Procedures,Transactions,Insert,Deadlock,我有一个存储过程,它根据某些条件在四个表中逐行插入。它工作得不太好,因为在某些情况下,它不会在其中一个表中插入行,我想这会导致死锁或类似的情况。这里是过程,但是为了更清楚地查看SP,insert语句被省略了。如果有必要,我将完整地发布它 在第二个IF语句的ELSE部分中,过程需要插入单行,但它不需要。所有其他部分都正确并插入,但在整个事务中,只有AvlDataSegmentStartPosition表保持不变,没有插入行 ALTER PROCEDURE [dbo].[Uspinsertintoa

我有一个存储过程,它根据某些条件在四个表中逐行插入。它工作得不太好,因为在某些情况下,它不会在其中一个表中插入行,我想这会导致死锁或类似的情况。这里是过程,但是为了更清楚地查看SP,insert语句被省略了。如果有必要,我将完整地发布它

在第二个IF语句的ELSE部分中,过程需要插入单行,但它不需要。所有其他部分都正确并插入,但在整个事务中,只有AvlDataSegmentStartPosition表保持不变,没有插入行

ALTER PROCEDURE [dbo].[Uspinsertintoavldata] (@DeviceId     BIGINT, 
                                              @AvlTimestamp DATETIME, 
                                              @Priority     TINYINT, 
                                              @Lon          REAL, 
                                              @Lat          REAL, 
                                              @Altitude     SMALLINT, 
                                              @Angle        SMALLINT, 
                                              @Satellites   TINYINT, 
                                              @Speed        SMALLINT, 
                                              @AvlDataId    BIGINT out) 
AS 
  BEGIN 
      BEGIN TRAN 

      DECLARE @oldAvlDataId BIGINT; 
      DECLARE @currentTime DATETIME = Getdate(); 

      INSERT INTO dbo.[avldata] ...

      SET @AvlDataId = @@identity 

      UPDATE dbo.[lastavldata] WITH (serializable) 
      SET    ...
      WHERE  [deviceid] = @DeviceId 
             AND [avltimestamp] < @AvlTimestamp 

      IF @@rowcount = 0 
         AND NOT EXISTS (SELECT * 
                         FROM   dbo.[lastavldata] 
                         WHERE  [deviceid] = @DeviceId) 
        BEGIN 
            INSERT INTO dbo.[lastavldata] ...
        END 

      UPDATE dbo.[lastavldatasegmentstartposition] WITH (serializable) 
      SET    ...
      WHERE  [deviceid] = @DeviceId 
             AND [avltimestamp] < @AvlTimestamp 
             AND ( ( [speed] < 5 AND @Speed >= 5 ) 
                    OR ( [speed] >= 5 AND @Speed < 5 ) ) 
      -- this is the IF statement where error occurs
      IF @@rowcount = 0
        -- when data comes here it is all right
        BEGIN 
            IF NOT EXISTS (SELECT * 
                           FROM   dbo.[lastavldatasegmentstartposition] 
                           WHERE  [deviceid] = @DeviceId) 
              BEGIN 
                  INSERT INTO dbo.[lastavldatasegmentstartposition] ...
              END 
            ELSE 
              SELECT @oldAvlDataId = a.avldataid 
              FROM   dbo.[avldatasegmentstartposition] a 
              WHERE  a.[avltimestamp] = 
                     (SELECT Min([avltimestamp]) 
                      FROM   dbo.[avldatasegmentstartposition] 
                      WHERE  [deviceid] = @DeviceId 
                             AND [avltimestamp] > @AvlTimestamp 
                     ) 
                     AND ( ( [speed] < 5 AND @Speed < 5 ) 
                            OR ( [speed] >= 5 AND @Speed >= 5 ) ) 

            IF @oldAvlDataId IS NOT NULL 
              BEGIN 
                  UPDATE dbo.[avldatasegmentstartposition] 
                  SET    ...
                  FROM   dbo.[avldatasegmentstartposition] 
                  WHERE  [avldataid] = @oldAvlDataId 
              END 
        END 
      ELSE
        -- WHEN DATA COMES HERE, ROW OFTEN IS NOT INSERTED IN FOLLOWING TABLE
        BEGIN 
            INSERT INTO dbo.[avldatasegmentstartposition] 
                    ([avldataid], 
                     [deviceid], 
                     [avltimestamp], 
                     [priority], 
                     [lon], 
                     [lat], 
                     [altitude], 
                     [angle], 
                     [satellites], 
                     [speed]) 
        VALUES      ( @AvlDataId, 
                      @DeviceId, 
                      @AvlTimestamp, 
                      @Priority, 
                      @Lon, 
                      @Lat, 
                      @Altitude, 
                      @Angle, 
                      @Satellites, 
                      @Speed) 
        END 

      COMMIT TRAN 
  END

如果有人需要更多的解释,就问。

你切得太多了。是否有一个选择或常量列表?顺便说一句,死锁是一个真正的异常,因此如果发生死锁,您会注意到。@IvanStarostin有SP输入参数被传递到SP并在其中使用。最后一次插入无效-死锁的来源是什么?@IvanStarostin已编辑。AvlDataId是首先插入的其他表的标识,所有其他参数都是输入参数。我知道了,谢谢。你有没有确保自己掉进了那个街区?在必须执行此insert的情况下,您是否检查是否达到此insert语句?在那里放置一个简单的打印测试并运行。你剪切太多了。是否有一个选择或常量列表?顺便说一句,死锁是一个真正的异常,因此如果发生死锁,您会注意到。@IvanStarostin有SP输入参数被传递到SP并在其中使用。最后一次插入无效-死锁的来源是什么?@IvanStarostin已编辑。AvlDataId是首先插入的其他表的标识,所有其他参数都是输入参数。我知道了,谢谢。你有没有确保自己掉进了那个街区?在必须执行此insert的情况下,您是否检查是否达到此insert语句?在其中放置一个简单的打印测试并运行。