2013-07-18 34 views
3

執行相應的操作我已創建AFTER INSERT觸發器如何忽略觸發錯誤和MS SQL Server中

現在,如果如果在執行觸發器出現錯誤無論如何。它不應該在觸發表上執行插入操作。

in一個字,如果任何錯誤發生在觸發器中,它應該忽略它。

正如我已經使用

BEGIN TRY 

END TRY 
BEGIN CATCH 

END CATCH 

但它給下面的錯誤信息並回滾Insert操作上觸發表

觸發器執行過程中引發錯誤。該批次已被中止 ,並且用戶事務(如果有的話)已被回滾。

+0

你可以發佈你的整個代碼? –

+0

由於目前在觸發代碼中沒有錯誤,但爲了安全起見,我需要在上線前做同樣的事情,所以如果在觸發器中發生任何錯誤,它不會影響插入操作 –

回答

4

有趣的問題。默認情況下,觸發器的設計是,如果它們失敗了,它們會回滾引發它的命令。所以無論何時觸發器執行都有一個活動事務,無論是否有明確的BEGIN TRANSACTION或不在外面。而且BEGIN/TRY裏面的觸發器也不起作用。您的最佳做法是不寫任何可能失敗的觸發代碼 - 除非還希望失敗觸發語句。

在這種情況下,要抑制此行爲,有一些解決方法。

選項A(醜陋的樣子):

由於交易是在觸發的開始活躍,你可以COMMIT並繼續與你的觸發命令:

CREATE TRIGGER tgTest1 ON Test1 AFTER INSERT 
AS 
BEGIN 
COMMIT; 
... do whatever trigger does 
END; 

注意,如果觸發代碼中存在錯誤,但仍會產生錯誤消息,但Test1表中的數據已安全插入。

選項B(也難看):

您可以從觸發移動你的代碼到存儲過程。然後從實現BEGIN/TRY的Wrapper SP調用該存儲過程,最後 - 從觸發器中調用Wrapper SP。如果需要在邏輯中(現在在SP中)需要,可能需要將INSERTED表中的數據移出來,這可能有點棘手 - 可能使用一些臨時表。

SQLFiddle DEMO

2

你不能,並且解決它的任何企圖是萬金油。 TRY/CATCH或@@ ERROR檢查將不會解決基本問題。

如果你想使用緊密耦合的觸發器,那麼你必須購買由耦合引起的較低的可用性。

如果你想保留可用性(即INSERT成功),那麼你必須放棄耦合(移除觸發器)。您必須在單獨的交易中執行您計劃在觸發器中執行的所有處理,在您執行INSERT後,開始執行之後的。針對新插入的行輪詢表的SQL代理作業,Service Broker啓動的過程甚至應用程序層步驟都將符合法案要求。