过程永远不会插入一些行 - SQL Server

时间:2016-02-26 10:51:37

标签: sql-server stored-procedures transactions insert deadlock

我有基于某些条件在四个表中逐行插入的存储过程。它不能很好地工作,因为在某些情况下它不会在其中一个表中插入行(我认为它来自DEADLOCK或类似的东西)。这是程序,但是为了更清晰的SP视图,省略了插入语句(如果有必要,我会将其完整发布)。

在第二个IF语句程序的ELSE部分需要插入SINGLE行,但它不会。 所有其他部分都是正确的并且已插入,但是从整个交易 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

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

0 个答案:

没有答案