"INSTEAD OF UPDATE " 触发器内部的 MSSQL 条件检查

MSSQL conditional check inside of "INSTEAD OF UPDATE " trigger

使用 MSSQL2008。

我有两个table。

TableResource
-------------
ID [bigint]
Attribute1 [int]
Attribute2 [int]
Attribute3 [int]
VersionId [uniqueidentifier]

TableResourceHistory
--------------------
ID [bigint]
Attribute3History [int]
HistoryDate [datetime]
VersionId [uniqueidentifier]

我有一个 instead of update 触发器需要完成两件事:

这是我目前所知道的,但是我在想出触发历史日志的相等比较时遇到了问题。

CREATE TRIGGER [dbo].[tr_UpdateResourceHistoryVersionId] ON [dbo].[TableResources]
INSTEAD OF UPDATE
AS
   SET NOCOUNT ON;
BEGIN                                           

-- ?? IF inserted.Attribute3 = deleted.Attribute3
-- ??  THEN we just pass the UPDATE through

UPDATE [TableResources]
SET 
    VersionId = inserted.VersionId,
    Attribute1 = inserted.Attribute1,
    Attribute2 = inserted.Attribute2        
FROM Inserted, TableResources
WHERE Inserted.ID = TableResources.ID

-- ??? ELSE, the Attribute3 field was updated, and we perform the history log
-- ??? and give it a new version number

-- History Log
INSERT TableResourceHistory (Attribute3History, HistoryDate, VersionId)
SELECT NEWID(), GETUTCDATE(), deleted.VersionId
FROM deleted    

-- pass through the update, but assign a new VersionId
UPDATE [TableResources]
  SET 
    VersionId = NEWID(),
    Attribute1 = inserted.Attribute1,
    Attribute2 = inserted.Attribute2        
FROM Inserted, TableResources
WHERE Inserted.ID = TableResources.ID   

END

有什么想法吗? TIA!

历史 table 插入只有在 Attribute3 发生变化时才会发生。

试试这个

CREATE TRIGGER [dbo].[tr_UpdateResourceHistoryVersionId]
ON [dbo].[TableResources]
INSTEAD OF UPDATE
AS
    SET NOCOUNT ON;

  BEGIN

      IF EXISTS(SELECT 1
                FROM   inserted i
                       JOIN deleted d
                         ON i.ID = d.ID
                            AND i.Attribute3 = d.Attribute3)
        BEGIN
            UPDATE T
            SET    VersionId = inserted.VersionId,
                   Attribute1 = inserted.Attribute1,
                   Attribute2 = inserted.Attribute2
            FROM   Inserted I
                   JOIN [TableResources] T
                     ON I.ID = T.ID
                   JOIN deleted d
                     ON i.ID = d.ID
                        AND i.Attribute3 = d.Attribute3
        END

      IF EXISTS(SELECT 1
                FROM   inserted i
                       JOIN deleted d
                         ON i.ID = d.ID
                            AND i.Attribute3 <> d.Attribute3)
        BEGIN
            INSERT TableResourceHistory
                   (Attribute3History,HistoryDate,VersionId)
            SELECT Newid(),
                   Getutcdate(),
                   d.VersionId
            FROM   deleted d
                   JOIN Inserted i
                     ON i.ID = d.ID
                        AND i.Attribute3 <> d.Attribute3

            -- pass through the update, but assign a new VersionId
            UPDATE T
            SET    VersionId = Newid(),
                   Attribute1 = inserted.Attribute1,
                   Attribute2 = inserted.Attribute2
            FROM   Inserted I
                   JOIN [TableResources] T
                     ON I.ID = T.ID
                   JOIN deleted d
                     ON i.ID = d.ID
                        AND i.Attribute3 <> d.Attribute3
        END
  END 

如果出现问题或未按预期工作,请在此答案下方的评论部分回复

我会这样做 拳头插入历史然后更新 我看不到你的属性 3 的任何更新,但我确实把它放在了我的触发器中 此外,历史日志中的 ID 似乎是唯一的 link 连接表,所以我猜它不是历史表中的主键

 CREATE TRIGGER [dbo].[tr_UpdateResourceHistoryVersionId] ON [dbo].[TableResources]
    INSTEAD OF UPDATE
    AS
       SET NOCOUNT ON;

BEGIN    

    -- History Log, insert the old Attribute3 value (If in the Set values)
    IF UPDATE(Attribute3)
    BEGIN
       INSERT TableResourceHistory (ID, HistoryDate, Attribute3History, VersionId)
       Select i.ID, GETUTCDATE(), d.Attribute3, d.versionId
       FROM inserted i 
       INNER JOIN deleted d on i.ID = d.ID
       WHERE i.Attribute3 <> d.Attribute3
    END

    -- Update the table Use NewID() when Attribute3 differs
    UPDATE T         SET 
        VersionId = Case when UPPDATE(Attribute3) AND i.Attribute3 <> d.Attribute3 then NewID() ELSE i.VersionId END,
        Attribute1 = i.Attribute1,
        Attribute2 = i.Attribute2,
        Attribute3 = i.Attribute3
    FROM [TableResources] T 
    INNER JOIN inserted i on i.ID = T.ID
    INNER JOIN deleted d on d.ID = i.ID

END

编辑: Chris 让我知道了 UPDATE(Field) 函数。

最好的问候 Lars Skogshus
Chris Chilvers

互补