2009-11-23 102 views
4

我需要執行一個ON DELETE CASCADE我的表名爲類,它具有以下columls CAT_ID(BIGINT) NAME(VARCHAR) PARENT_CAT_ID(BIGINT )SQL服務器:自引用FK,觸發代替ON DELETE CASCADE

PARENT_CAT_ID是CAT_ID上的FK。顯然,可愛的SQL Server不允許我使用ON DELETE CASCADE聲明循環或多條路徑來刪除。

我經常看到的解決方案是觸發器。我做了以下觸發:

USE [ma] 
GO 
/****** Object: Trigger [dbo].[TRG_DELETE_CHILD_CATEGORIES] Script Date: 11/23/2009 16:47:59 ******/ 
SET ANSI_NULLS ON 
GO 
SET QUOTED_IDENTIFIER ON 
GO 
ALTER TRIGGER [dbo].[TRG_DELETE_CHILD_CATEGORIES] ON [dbo].[CATEGORY] FOR DELETE AS 
SET NOCOUNT ON 
/* * CASCADE DELETES TO '[Tbl B]' */ 
DELETE CATEGORY FROM deleted, CATEGORY WHERE deleted.CAT_ID = CATEGORY.PARENT_CAT_ID 

當我手動刪除與子類別的類別,我得到以下異常:

exception

任何想法有什麼不對我的觸發器?

UPDATE: 很抱歉的編輯,但我有另一列CATEGORY.CAT_SCH_ID,這是另一個表CAT_SCH.ID的FK。這個FK也有一個CASCADE DELETE,這意味着一旦我刪除一個CAT_SCH,它的CATEGORIES也必須被刪除。因此,當我定義觸發器時,出現此錯誤:

無法在表'CATEGORY'上創建INSTEAD DELETE或INSTEAD UPDATE TRIGGER'TRG_DEL_CATEGORY_WITH_CHILDREN'。這是因爲該表具有帶級聯DELETE或UPDATE的FOREIGN KEY。

任何想法?

回答

12

原始DELETE已執行後,將刪除觸發器。要遞歸刪除,您需要編寫一個INSTEAD OF DELETE觸發器。

的算法是這樣的:

  • 插入的PK從刪除到一個臨時表

  • 在臨時表中找到的記錄詳細記錄

  • 循環播放,直到沒有更多的記錄找到

DELETE記錄在t他通過加入臨時表來表格。

我描述了遞歸刪除in my blog

更新

我猜你只需要丟棄來自於分類的遞歸外鍵DELETE CASCADE標誌。來自CAT_SCH的外鍵上的CASCADE標誌應該沒有關係。

+0

感謝您的迴應!這看起來正是我需要的,但是有一個小問題,你可以看看更新嗎?謝謝。 – 2009-11-23 16:18:02

+0

對不起,但不能在刪除級聯上的表上定義'INSTEAD OF DELETE'... – Bellash 2014-09-18 11:51:15