SQL对UPDATE触发器中的每个更新的行执行INSERT

时间:2019-07-18 17:42:52

标签: sql sql-server sql-server-2016 database-trigger

我有一个AFTER UPDATE触发器,几乎总是一次对多行执行。发生这种情况时,它需要进行更新,删除和插入。对于更新/删除,我正在处理多个行,如下所示:

DELETE lss
FROM dbo.Lab_SubSpace lss
JOIN Inserted i ON lss.Lab_Space_Id = i.id
WHERE i.Occupancy_Status_code = 'vacant' OR i.Status_Code IN ('retired', 'unknown');

尽管现在我遇到的困难是,我还需要为每行更新的表插入另一个表。除了仅使用游标在Inserted表上循环然后执行INSERT INTO操作外,我不确定如何处理。像这样:

DECLARE c CURSOR 
FAST_FORWARD READ_ONLY LOCAL 
FOR SELECT i.id, i.Floor_Space_Area_Qty, sp.WWID
FROM Inserted i
JOIN dbo.Space_Planners sp ON i.Building_Location_Id = sp.LocationId
WHERE i.Status_Code NOT IN ('retired', 'unknown');

OPEN c

FETCH NEXT FROM c INTO @labSpaceId, @sqFt, @poc;

WHILE @@FETCH_STATUS = 0
BEGIN
    INSERT INTO dbo.Lab_SubSpace (...)
    VALUES (@labSpaceId, @sqFt, @poc, ...);

    FETCH NEXT FROM c INTO @labSpaceId, @sqFt, @poc;
END

有更好的方法吗?

2 个答案:

答案 0 :(得分:3)

与其使用inerted遍历cursor表并一一插入记录,不如使用insert...select

INSERT INTO dbo.Lab_SubSpace (...)
SELECT i.id, i.Floor_Space_Area_Qty, sp.WWID
FROM Inserted i
JOIN dbo.Space_Planners sp 
    ON i.Building_Location_Id = sp.LocationId
WHERE i.Status_Code NOT IN ('retired', 'unknown');

答案 1 :(得分:1)

你能尝试

INSERT INTO dbo.Lab_Subspace(<field1>, <field2>, <field3>)
SELECT i.id, i.Floor_Space_Area_Qty, sp.WWID
FROM Inserted i
JOIN dbo.Space_Planners sp ON i.Building_Location_Id = sp.LocationId
WHERE i.Status_Code NOT IN ('retired', 'unknown')