Sql-Server-2008
SQL Server:更新觸發器在插入觸發器之前觸發
我有一個帶有 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
考慮到a)觸發器自然是觸發觸發器的DML語句的事務的一部分,並且b)在行存在之前不能在行上發生更新,實際的更新不可能在實際的插入之前出現. 因此,正在發生其他事情。
需要考慮的事項:
- 問題中顯示的觸發器定義是實際的和目前的定義嗎?是否有可能
Comment
在觸發器中切換“插入”和“更新”的值,以便插入觸發器具有“更新”的註釋,反之亦然?- 觸發器是否有可能
UPDATE
以某種方式定義為AFTER INSERT, UPDATE
?如果是這樣,一個INSERT
操作將觸發兩個觸發器,使其看起來既是一個INSERT
又是一個UPDATE
發生,而實際上沒有UPDATE
操作(這也可以解釋為什麼審計條目的時間僅相隔幾毫秒)。- 您確定“相應”記錄的查詢是否可能存在缺陷並且結果具有誤導性?
我剛剛發生了這種確切的情況並弄清楚發生了什麼(至少對於我的情況)。我的桌子上有一個舊的第三個觸發器,它是這樣的:
CREATE TRIGGER [dbo].[MyTrigger_fi] ON [dbo].[theTable] FOR INSERT AS UPDATE theTable SET ReportingDate = ot.ReportingDate FROM Inserted i JOIN theTable tb ON tb.ID = i.ID JOIN OtherTable ot on ot.ID = tb.OtherTableID
FOR INSERT 發生在我的 AFTER INSERT 之前,執行更新,然後觸發了我的 AFTER UPDATE 觸發器。最終結果是在每次插入時在我的插入消息之前記錄一條更新消息。一切都是這樣的:
Record Inserted FOR INSERT trigger fires Record is Updated AFTER UPDATE trigger fires Update Event is recorded AFTER INSERT trigger fires Insert Event is recorded