Sql server 过程从不插入某些行-SQL Server
我有一个存储过程,它根据某些条件在四个表中逐行插入。它工作得不太好,因为在某些情况下,它不会在其中一个表中插入行,我想这会导致死锁或类似的情况。这里是过程,但是为了更清楚地查看SP,insert语句被省略了。如果有必要,我将完整地发布它 在第二个IF语句的ELSE部分中,过程需要插入单行,但它不需要。所有其他部分都正确并插入,但在整个事务中,只有AvlDataSegmentStartPosition表保持不变,没有插入行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
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语句?在其中放置一个简单的打印测试并运行。