SQL Server:更新触发器在插入触发器之前触发

dlh*_*dlh 6 trigger sql-server-2008

我有一个带有 SQL Server 托管数据库的应用程序。我无权访问应用程序代码,但我可以完全访问数据库。我已将自己的自定义审计添加到表中以帮助调试。

我正在使用after触发器。以下是我的触发器的简化版本。

问题:我看到update在相应insert审计记录之前的审计记录。这怎么可能?差异只有几毫秒,对于我目前的目的并不重要,但我可以想象更糟糕的情况,其中程序逻辑取决于正确的年表。

我知道在相同类型的触发器(全部insert或全部update)之间控制触发器执行顺序的方法。我可以对异构触发器执行顺序做出哪些假设?

create trigger dbo.MyTrigger_i on dbo.theTable
after insert
as
begin
    set nocount on
    declare @Date datetime, @User sysname
    set @Date = GETDATE()
    set @User = SUSER_SNAME()
    insert into MyAudit (RowID, [Date], UserName, Comment)
            select i.ID, @Date, @User, 'Insert'
            from 
                inserted as i
end
go

create trigger dbo.MyTrigger_u on dbo.theTable
after update
as
begin
    set nocount on
    declare @Date datetime, @User sysname
    set @Date = GETDATE()
    set @User = SUSER_SNAME()
    insert into MyAudit (RowID, [Date], UserName, Comment)
            select 
                i.ID, @Date, @User, 'Update'
            from
                inserted as i
                inner join deleted as d
                    on i.ID = d.ID
end
go
Run Code Online (Sandbox Code Playgroud)

Ali*_*ghi 0

如果我理解你的问题,那就是 SQL Server 中的“后触发器”将传递当前的日期时间,即实际事件发生后几毫秒。你如何使它们匹配。

您可以尝试在 1 个事务开始时将日期时间作为变量获取,并将该值传递到审核表。这对你有用吗?这样,这就是交易开始时的情况。

您可以使用该行上任何适用列的触发器强制执行最后更新的列。然后您获得“上次更新”值,最后,您的第二个触发器会将这两个值复制到审核表。这将需要嵌套触发器,但这通常是不行的。我个人会选择将日期时间作为变量,并在需要时使用事务传递它。