【问题标题】:SQL perform INSERT for every updated row in UPDATE triggerSQL 对 UPDATE 触发器中的每个更新行执行 INSERT
【发布时间】:2019-07-18 17:42:52
【问题描述】:

我有一个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

有没有更好的办法?

【问题讨论】:

  • YES!!!! 触发器内的光标可能是你能做的最慢的事情! !请改用适当的、基于集合的方法....

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


【解决方案1】:

不要使用cursor 遍历inerted 表并一一插入记录,只需使用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');

【讨论】:

    【解决方案2】:

    你可以试试

    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')
    

    【讨论】:

    • 我正在寻找掌上表情符号:)
    猜你喜欢
    • 2013-12-11
    • 2011-12-04
    • 1970-01-01
    • 2012-02-02
    • 1970-01-01
    • 2021-12-20
    • 1970-01-01
    • 2015-11-26
    • 1970-01-01
    相关资源
    最近更新 更多