Sql-Server

防止“最後一個”觸發器不必要地觸發

  • April 18, 2019

我們有一個在 SQL Server 2008 R2 上執行的舊應用程序。

在對其中一些遺留表進行 DML 操作時,我需要將數據寫入同一實例下另一個數據庫中的一組表。

這些舊表已經有自己的INSERT/UPDATE觸發器,我無法修改它們。

公司不願意/不能冒險使用變更跟踪/複製技術。

我決定在這些表上使用額外的INSERT&UPDATE觸發器,並將我的觸發器標記為 Last using sp_settriggerorder。但是,舊INSERT觸發器會更新同一個表中的數據,該表會觸發舊UPDATE觸發器,然後是我的 Last Update 觸發器。

例如 Table1 有insert_trigger並且update_trigger我添加了我的 Last 觸發器myLast_insert_triggermyLast_update_trigger. insert_trigger有更新:

UPDATE Table1 set c1 = getdate() 
from inserted 
where inserted.primkey = Table1.primkey

這會觸發update_triggermyLast_update_trigger最後myLast_insert_trigger按那個順序觸發。這是意料之中的,但我不想myLast_update_trigger在這裡被解僱。有沒有簡單的方法來實現這一目標?

我正在考慮查詢系統表並trigger_NestLevel在最後一個觸發器中繞過最後一個觸發器邏輯,但這使我的實現更加複雜。

如果有任何人都可以建議的觸發器以外的機制(但不是更改跟踪/複製:)),我將不勝感激。

公司不願意/不能冒險使用變更跟踪/複製技術

但是願意/能夠讓您添加觸發器?這沒有多大意義。

無論如何,請考慮將您自己的 INSTEAD OF 觸發器添加到目標表的“前端”DML。將更改應用到目標表和其他數據庫中的表。

這樣你就可以讓 AFTER 觸發器保持原樣。

從性能角度和數據完整性角度來看,觸發器並不是真正的正確方法。如果公司擔心複製和/或更改跟踪的風險,那麼很可能沒有向他們正確解釋,您的數據可能存在更多的風險,尤其是考慮到您已經看到這樣的問題。批量插入會發生什麼,如果有人從遺留數據庫或輔助數據庫中刪除數據會發生什麼,你如何重新植入數據?

**一種選擇:**不是創建新觸發器,而是創建一個接受表值參數的儲存過程,以執行自定義觸發器的 INSERT 和 UPDATE 邏輯,然後修改現有觸發器以適當呼叫此儲存過程,而不是多個觸發器觸發,您的額外邏輯被稱為原始觸發邏輯的一部分。

這也有一些觸發解決方案的缺陷,但否定了觸發順序問題。

**另一種選擇:**確定數據延遲限制——第二個數據庫中的數據可以落後多遠?如果稍微落後一點是可以接受的,那麼編寫一個儲存過程來對遺留數據庫進行快照,並使用MERGE語句將數據 UPSERT 到第二個數據庫中(假設數據量不是太大而不會使這個過程太慢)。每N分鐘將其作為代理作業執行一次,具體取決於所需時間和您的延遲要求。

該解決方案不是實時更新,但至少提供了一個種子解決方案並將對性能的影響降至最低。

引用自:https://dba.stackexchange.com/questions/235080