防止“最後一個”觸發器不必要地觸發
我們有一個在 SQL Server 2008 R2 上執行的舊應用程序。
在對其中一些遺留表進行 DML 操作時,我需要將數據寫入同一實例下另一個數據庫中的一組表。
這些舊表已經有自己的
INSERT/UPDATE
觸發器,我無法修改它們。公司不願意/不能冒險使用變更跟踪/複製技術。
我決定在這些表上使用額外的
INSERT
&UPDATE
觸發器,並將我的觸發器標記為 Last usingsp_settriggerorder
。但是,舊INSERT
觸發器會更新同一個表中的數據,該表會觸發舊UPDATE
觸發器,然後是我的 Last Update 觸發器。例如 Table1 有
insert_trigger
並且update_trigger
我添加了我的 Last 觸發器myLast_insert_trigger
和myLast_update_trigger
.insert_trigger
有更新:UPDATE Table1 set c1 = getdate() from inserted where inserted.primkey = Table1.primkey
這會觸發
update_trigger
,myLast_update_trigger
最後myLast_insert_trigger
按那個順序觸發。這是意料之中的,但我不想myLast_update_trigger
在這裡被解僱。有沒有簡單的方法來實現這一目標?我正在考慮查詢系統表並
trigger_NestLevel
在最後一個觸發器中繞過最後一個觸發器邏輯,但這使我的實現更加複雜。如果有任何人都可以建議的觸發器以外的機制(但不是更改跟踪/複製:)),我將不勝感激。
公司不願意/不能冒險使用變更跟踪/複製技術
但是願意/能夠讓您添加觸發器?這沒有多大意義。
無論如何,請考慮將您自己的 INSTEAD OF 觸發器添加到目標表的“前端”DML。將更改應用到目標表和其他數據庫中的表。
這樣你就可以讓 AFTER 觸發器保持原樣。
從性能角度和數據完整性角度來看,觸發器並不是真正的正確方法。如果公司擔心複製和/或更改跟踪的風險,那麼很可能沒有向他們正確解釋,您的數據可能存在更多的風險,尤其是考慮到您已經看到這樣的問題。批量插入會發生什麼,如果有人從遺留數據庫或輔助數據庫中刪除數據會發生什麼,你如何重新植入數據?
**一種選擇:**不是創建新觸發器,而是創建一個接受表值參數的儲存過程,以執行自定義觸發器的 INSERT 和 UPDATE 邏輯,然後修改現有觸發器以適當呼叫此儲存過程,而不是多個觸發器觸發,您的額外邏輯被稱為原始觸發邏輯的一部分。
這也有一些觸發解決方案的缺陷,但否定了觸發順序問題。
**另一種選擇:**確定數據延遲限制——第二個數據庫中的數據可以落後多遠?如果稍微落後一點是可以接受的,那麼編寫一個儲存過程來對遺留數據庫進行快照,並使用MERGE語句將數據 UPSERT 到第二個數據庫中(假設數據量不是太大而不會使這個過程太慢)。每N分鐘將其作為代理作業執行一次,具體取決於所需時間和您的延遲要求。
該解決方案不是實時更新,但至少提供了一個種子解決方案並將對性能的影響降至最低。