2016-11-07 15 views
0

我有我的觸發器中的缺陷在哪裏用軟刪除覆蓋DELETE?

CREATE TRIGGER [CantDeleteStuff] ON [dbo].[Stuff] 
INSTEAD OF DELETE 
AS 
BEGIN 
    ROLLBACK 
    UPDATE [dbo].[Stuff] SET [Deleted]=1 FROM DELETED WHERE [dbo].[Stuff].[Id] = DELETED.[Id] 
END 
GO 

創建一個觸發器,我認爲它的意圖十分明顯。但是當我嘗試刪除一行時,出現錯誤

事務在觸發器中結束。該批次已被中止。

如何修復?

+0

只要刪除回滾語句,你應該沒問題。請記住,您將不會觸發刪除的INSTEAD。這意味着不會發生刪除事件。 –

回答

2

而不是刪除將取代與您的觸發代碼的刪除。

根據Technet的說法,觸發器的回滾是問題所在。你可以在這裏閱讀更多。

觸發器的操作就好像執行觸發器時有效的未完成事務一樣。無論觸發觸發器的語句是隱式事務還是顯式事務,都是如此。

當語句開始在自動提交模式下執行時,有一個隱含的BEGIN TRANSACTION允許恢復由語句生成的所有修改,如果遇到錯誤。此隱含事務對批處理中的其他語句沒有影響,因爲它在語句完成時提交或回滾。但是,當觸發器被調用時,該隱含事務仍然有效。

當觸發器執行時,隱式事務開始。如果觸發器完成執行並且@@ TRANCOUNT = 0,則會發生錯誤3609,並終止批處理。如果在觸發器中發出BEGIN TRANSACTION語句,它將創建一個嵌套事務。在這種情況下,執行COMMIT TRANSACTION語句時,該語句將只應用於嵌套事務。 在觸發器中使用ROLLBACK TRANSACTION時,請注意以下行爲:

在當前事務中對該點進行的所有數據修改都會回滾,包括由觸發器所做的任何修改。

觸發器在ROLLBACK語句後繼續執行任何剩餘的語句。如果任何這些語句修改數據,則修改不會回滾。

觸發器中的ROLLBACK關閉並釋放所有在包含觸發觸發器的語句的批處理中聲明和打開的遊標。這包括由觸發觸發器的批處理所調用的存儲過程中聲明和打開的遊標。在觸發觸發器的批次之前在批處理中聲明的遊標只能關閉。但是,如果出現以下情況,STATIC或INSENSITIVE遊標將保持打開狀態:

CURSOR_CLOSE_ON_COMMIT已設置爲OFF。 靜態遊標是同步遊標或完全填充的異步遊標。 而不是使用ROLLBACK TRANSACTION,SAVE TRANSACTION語句可用於在觸發器中執行部分回滾。

https://technet.microsoft.com/en-us/library/ms187844(v=sql.105).aspx

所以只是刪除回滾。