在“INSTEAD OF UPDATE”触发器内部进行MSSQL条件检查

时间:2016-10-27 16:15:14

标签: sql-server sql-server-2008 tsql database-trigger

使用MSSQL2008。

我有两张桌子。

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

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

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

  • 如果字段“TableReResource.Attribute3”已更改,则使用“旧”Attribute3值将历史记录写入历史记录表,并修改{{1}的“TableResource.VersionId”字段} table。
  • 如果“TableResource”没有变化,则直接通过更新。

到目前为止,这是我所拥有的,但是我无法通过相等比较来触发历史记录日志。

TableReResource.Attribute3

有什么想法吗? TIA!

2 个答案:

答案 0 :(得分:1)

历史记录表插入仅在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 

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

答案 1 :(得分:1)

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

 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