2012-04-19 99 views
10

比方說,我有一個層次3個表:INSTEAD OF觸發器和CASCADE路徑

TableA -> TableB -> TableC 

TableCTableB一個外鍵關係,並TableBTableA一個外鍵關係。

如果我刪除TableA中的記錄,它應該級聯刪除整個層次結構。使用ON DELETE CASCADE會正常工作。

但是讓我們假設我需要在TableC上放置一個INSTEAD OF觸發器。我的理解是,INSTEAD OF觸發器不能放在具有刪除級聯的表上。取自MSDN:

對於INSTEAD OF觸發器,在具有指定級聯動作ON DELETE的參照關係的表上不允許使用DELETE選項。

如果我必須採取級聯刪除掉TableB->TableC,我需要使用INSTEAD OF觸發強制執行參照完整性,然後我有同樣的問題與TableB->TableA。這是一個簡單的例子,但想象一下級聯路徑要大得多。它似乎可以在整個漫長的瀑布路徑中輕鬆滾動。

那麼,處理這種情況的最佳做法是什麼?

+1

你想觸發器做什麼(而不是刪除),不會破壞參照完整性? – 2012-04-19 08:54:09

+0

我想避免在示例中增加更多複雜因素,因爲我不是在尋找表格重新設計解決方案,而是針對特定場景的答案。但是作爲參考,TableC使用鄰接列表模型來存儲層次結構。我使用INSTEAD OF觸發器遞歸刪除整個層次結構。由於使用SS2005,HierarchyID是不可能的。 – 2012-04-19 09:03:59

+2

沒有重新設計表格,這可能會有所幫助:[SQL Server:使用自引用FOREIGN KEY刪除](http://explainextended.com/2010/03/03/sql-server-deleting-with-self-referential-外鍵/) – 2012-04-19 09:13:44

回答

3

假設您必須使用INSTEAD OF觸發器,並且AFTER觸發器不是一個選項,最好的方法是a)嚴格控制模式,以便b)以常規方式腳本化INSTEAD OF觸發器以實現CASCADE DELETE和其他你需要的操作。

像以前一樣創建FK約束,但不包含任何級聯行爲。在FK名稱,使用一些約定,表明應該發生什麼樣的級聯行爲和自定義行爲,如:

  • FK_UC_DC_Table1_Table2 - 級聯更新,刪除級聯
  • FK_UC_DN_Table1_Table3 - 級聯更新,刪除設置爲null

使用任何有意義的東西,但是創建FK,它們是代碼生成的有用元數據,您可以使用FK名稱來爲代碼生成器記錄指令。

然後,我會更進一步,並將這些表分離到各自的模式中。它們不會像其他表格那樣工作,並且在測試和優化代碼生成時,它們將首先變得越來越麻煩。最好保留所有這些隔離,並且容易通過普通容器識別。

專用模式還會通知任何修改數據的人,即不同的規則和行爲適用。

3

標準的最佳做法是觸發器,而不是定義上意見,而不是

如果您必須在FK更新/刪除中使用觸發器,最好使用AFTER,因爲它始終會執行。

如果您想要取消級聯動作但保留FK,只需將FK動作設置爲NO ACTION。

+0

不幸的是,AFTER觸發器在這種情況下不是解決方案,因爲在觸發器被觸發之前觸發完整性將被違反。 – 2012-06-08 07:53:35

+0

你可以更具體地說明你想讓觸發器做些什麼嗎? – matchdav 2012-06-08 20:55:11

+0

請參閱問題下的第二條評論。然而,我並不十分關心實施,而是人們會爲通用情景做些什麼。我很欣賞這可能取決於實施,但仍然! – 2012-06-09 14:53:22

相關問題