【问题标题】:SQL Update query is causing two rows in a triggerSQL 更新查询导致触发器中有两行
【发布时间】:2011-05-28 09:05:52
【问题描述】:

我使用 SQL Server 2005 并且有以下问题:

table A 上,我有一个触发器,可以跟踪对它的任何插入/更新/删除。跟踪记录被插入到审计表 (aAudit) 中。当我在A 上运行更新时,我在审计表中看到每个更新的两行,这不是我所期望的。这是我定义的触发器:

ALTER TRIGGER [ATrigger] ON [dbo].[A]
FOR INSERT, UPDATE, DELETE
AS
INSERT INTO [dbo].[aAudit]
([BusinessDate], [DataTypeId], [BookId], [Version], [DelFlag], [AuditDate], [ExtStatus])
SELECT [BusinessDate], [DataTypeId], [BookId], [Version], 'N', getDate(), 0
FROM inserted

INSERT INTO [dbo].[aAudit]
([BusinessDate], [DataTypeId], [BookId], [Version], [DelFlag], [AuditDate], [ExtStatus])
SELECT [BusinessDate], [DataTypeId], [BookId], [Version], 'Y', getDate(), 0
FROM deleted

为什么上面的触发器会在审计表中产生一行DelFlag = 'Y'和一行DelFalg = 'N'

感谢您查看我的问题。

维克拉姆

【问题讨论】:

    标签: sql sql-server sql-server-2005 triggers sql-update


    【解决方案1】:

    在幕后,UPDATE 被视为删除旧行并插入新行。因此,当您进行更新时,INSERTED 和 DELETED 记录集都包含数据。

    这就是为什么两行从 UPDATE 语句进入审计表的原因。

    【讨论】:

    • +1 点 - UPDATE 被视为 INSERT/DELETE 组合操作
    • 如果是这种情况,有没有办法处理它?我希望任何插入/更新都作为“未删除”进入审计表,任何已删除的行作为“已删除”。
    • @Vikram:是的,你可以做到 - 你只需要在触发器中进行更多检查 - 请参阅我的回复了解详细信息
    【解决方案2】:

    为了将INSERT、UPDATE、DELETE这三个操作分开,需要做额外的检查:

    ALTER TRIGGER [ATrigger] ON [dbo].[A]
    FOR INSERT, UPDATE, DELETE
    AS
       -- those are true INSERTs - the (ID) as primary key is *not* present in the "Deleted" table
       INSERT INTO [dbo].[aAudit]([BusinessDate], [DataTypeId], [BookId], [Version], [DelFlag], [AuditDate], [ExtStatus])
          SELECT [BusinessDate], [DataTypeId], [BookId], [Version], 'N', getDate(), 0
          FROM inserted 
          WHERE (id) NOT IN (SELECT DISTINCT (id) FROM DELETED)
    
       -- those are true DELETEs - the (ID) as primary key is *not* present in the "Inserted" table
       INSERT INTO [dbo].[aAudit]([BusinessDate], [DataTypeId], [BookId], [Version], [DelFlag], [AuditDate], [ExtStatus])
          SELECT [BusinessDate], [DataTypeId], [BookId], [Version], 'Y', getDate(), 0
          FROM deleted
          WHERE (id) NOT IN (SELECT DISTINCT (id) FROM INSERTED)
    
       -- those are the UPDATEs - the (ID) as primary key is present in both the "Inserted" and "Deleted" table
       INSERT INTO [dbo].[aAudit]([BusinessDate], [DataTypeId], [BookId], [Version], [DelFlag], [AuditDate], [ExtStatus])
          SELECT [BusinessDate], [DataTypeId], [BookId], [Version], 'N', getDate(), 0
          FROM Inserted i
          INNER JOIN Deleted d on i.ID = d.ID
    

    【讨论】:

    • @Vikram - 你应该接受(点击复选框)一个答案。这鼓励人们为您提供帮助,并让其他搜索者知道哪个答案更正了问题
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2012-11-14
    • 1970-01-01
    • 1970-01-01
    • 2018-05-25
    • 1970-01-01
    • 2023-01-27
    • 2012-11-16
    相关资源
    最近更新 更多