首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >在处理多个插入/更新记录时使用SQL触发器上的IF更新

在处理多个插入/更新记录时使用SQL触发器上的IF更新
EN

Stack Overflow用户
提问于 2016-06-16 17:47:53
回答 2查看 5.6K关注 0票数 0

我使用这个Server触发器从一个特定的表中查找多个记录的插入/更新,并将其放入另一个队列表中(供以后处理)。

代码语言:javascript
运行
复制
ALTER TRIGGER [dbo].[IC_ProductUpdate] ON [dbo].[StockItem]
AFTER INSERT, UPDATE
AS
BEGIN
    SELECT RowNum = ROW_NUMBER() OVER(ORDER BY ItemID) , ItemID
    INTO #ProductUpdates
    FROM INSERTED;

    DECLARE @MaxRownum INT;
    SET @MaxRownum = (SELECT MAX(RowNum) FROM #ProductUpdates);

    DECLARE @Iter INT;
    SET @Iter = (SELECT MIN(RowNum) FROM #ProductUpdates);

    WHILE @Iter <= @MaxRownum
    BEGIN
        -- Get Product Id
        DECLARE @StockItemID INT = (SELECT ItemID FROM #ProductUpdates WHERE RowNum = @Iter);

        -- Proceed If This Product Is Sync-able
        IF (dbo.IC_CanSyncProduct(@StockItemID) = 1)
        BEGIN
            -- Check If There Is A [ProductUpdate] Queue Entry Already Exist For This Product
            IF ((SELECT COUNT(*) FROM IC_ProductUpdateQueue WHERE StockItemID = @StockItemID) > 0)
            BEGIN
                -- Reset [ProductUpdate] Queue Entry
                UPDATE IC_ProductUpdateQueue 
                SET Synced = 0
                WHERE StockItemID = @StockItemID
            END
            ELSE
            BEGIN
                -- Insert [ProductUpdate] Queue Entry
                INSERT INTO IC_ProductUpdateQueue (StockItemID, Synced) 
                VALUES (@StockItemID, 0)
            END
        END

        SET @Iter = @Iter + 1;
    END

    DROP TABLE #ProductUpdates;
END

这很好,但是我只希望上面的触发器在某些列被更新时做出反应。

我感兴趣的专栏是:

  • 名字
  • 描述

我知道我可以使用以下the语法来检查一个列是否真的更新了(在update事件期间):

代码语言:javascript
运行
复制
IF (UPDATE(Name) OR UPDATE(Description))
BEGIN
    // do something...
END

但是,我不知道如何将它合并到上面的触发器中,因为我的触发器同时处理多个行的更新。

有什么想法吗?在触发器的哪一点,我可以使用IF (UPDATE(colX))吗?

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2016-06-16 19:12:50

首先,我建议为每个操作设置一个单独的触发器--一个用于INSERT,另一个用于UPDATE。保持代码更干净(减少混乱的IF语句等等)。

INSERT触发器非常简单,因为无需检查更新--而且绝对不需要临时表和缓慢的WHILE循环--只有两个简单的、基于集合的语句就完成了:

代码语言:javascript
运行
复制
CREATE TRIGGER [dbo].[IC_ProductInsert] ON [dbo].[StockItem]
AFTER INSERT
AS
BEGIN
    -- update the queue for those entries that already exist                 
    -- those rows that *DO NOT* exist yet are not being touched
    UPDATE puq
    SET Synced = 0
    FROM dbo.IC_ProductUpdateQueue puq
    INNER JOIN Inserted i ON puq.StockItemID = i.StockItemID

    -- for those rows that don't exist yet - insert the values
    INSERT INTO dbo.IC_ProductUpdateQueue (StockItemID, Synced) 
        SELECT 
            i.StockItemID, 0
        FROM
            Inserted i
        WHERE 
            NOT EXISTS (SELECT * FROM dbo.IC_ProductUpdateQueue puq
                        WHERE puq.StockItemID = i.StockItemID)
END

UPDATE触发器需要进行一次额外的检查,以查看两列中的一列是否发生了变化。通过将Inserted伪表与新值(在UPDATE之后)和Deleted伪表与“旧”值(在UPDATE之前)组合,可以很容易地处理这一问题:

代码语言:javascript
运行
复制
ALTER TRIGGER [dbo].[IC_ProductUpdate] ON [dbo].[StockItem]
AFTER UPDATE
AS
BEGIN
    -- update the queue for those entries that already exist                 
    -- those rows that *DO NOT* exist yet are not being touched
    UPDATE puq
    SET Synced = 0
    FROM dbo.IC_ProductUpdateQueue puq
    INNER JOIN Inserted i ON puq.StockItemID = i.StockItemID
    INNER JOIN Deleted d ON d.StockItemID = i.StockItemID
    WHERE
        i.Name <> d.Name OR i.Description <> d.Description

    -- for those rows that don't exist yet - insert the values
    INSERT INTO dbo.IC_ProductUpdateQueue (StockItemID, Synced) 
        SELECT 
            i.StockItemID, 0
        FROM
            Inserted i
        INNER JOIN 
            Deleted d ON d.StockItemID = i.StockItemID
        WHERE 
            i.Name <> d.Name OR i.Description <> d.Description
            AND NOT EXISTS (SELECT * FROM dbo.IC_ProductUpdateQueue puq
                            WHERE puq.StockItemID = i.StockItemID)
END
票数 2
EN

Stack Overflow用户

发布于 2016-06-16 17:58:05

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/37866093

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档