2017-02-14 54 views
3

我有一個自引用的註釋表。 我試圖在刪除級聯寫,但它需要一些例外刪除自引用表級聯

Introducing FOREIGN KEY constraint 'FK_Comments_Comments' on table 'Comments' may cause cycles or multiple cascade paths. Specify ON DELETE NO ACTION or ON UPDATE NO ACTION, or modify other FOREIGN KEY constraints.

,然後嘗試寫一個觸發器,但它採取例外再次

CREATE TRIGGER [dbo].[T_comment_Trigger] 
    ON [dbo].[Comments] 
    FOR DELETE 
AS 
    DELETE FROM Comments 
    WHERE ParentId =(SELECT deleted.id FROM deleted) 

couldn't delete rows that have children

我怎麼可以刪除級聯的做我的自引用表?

+2

這將真正幫助,如果你*關注*錯誤信息*將他們的文本複製到問題*中,而不是僅僅說「它不例外」。 –

+0

你的觸發器有一個主要問題。它假定只有一行被刪除。你需要爲這種類型的事情使用聯接。 –

+0

@Damien_The_Unbeliever我編輯我的問題 – Mike

回答

6

假設你保持你的FOREIGN KEY約束,你不能在FOR DELETE觸發器中解決問題。 FOR觸發器(也稱爲AFTER觸發器)激活活動已發生。並且如果外鍵具有引用,則會阻止行被刪除。在刪除之前發生外鍵檢查。

你需要的是一個INSTEAD OF觸發器。您還需要記住,您當前的觸發器只試圖處理一個「級別」的引用。 (因此,如果連續3引用第2行和第2行引用第1行,並刪除第1行,你只觸發試圖刪除第二行)

所以,像這樣:

CREATE TRIGGER [dbo].[T_comment_Trigger] 
    ON [dbo].[Comments] 
    INSTEAD OF DELETE 
AS 
    ;WITH IDs as (
     select id from deleted 
     union all 
     select c.id 
     from Comments c 
       inner join 
      IDs i 
       on 
       c.ParentID = i.id 
    ) 
    DELETE FROM Comments 
    WHERE id in (select id from IDs); 

如果有其他(非自引用)級聯外鍵約束,它們都必須由此觸發器中的操作替換。在這種情況下,我建議引入表變量來保存最終會被從Comments表中刪除所有的ID列表:

CREATE TRIGGER [dbo].[T_comment_Trigger] 
    ON [dbo].[Comments] 
    INSTEAD OF DELETE 
AS 
    declare @deletions table (ID varchar(7) not null); 
    ;WITH IDs as (
     select id from deleted 
     union all 
     select c.id 
     from Comments c 
       inner join 
      IDs i 
       on 
       c.ParentID = i.id 
    ) 
    insert into @deletions(ID) 
    select ID from IDs 

    DELETE FROM OtherTable 
    WHERE CommentID in (select ID from @deletions) 

    --This delete comes last 
    DELETE FROM Comments 
    WHERE id in (select ID from @deletions); 
+0

錯誤:**無法在表'dbo.Comments'上創建INSTEAD DELETE或INSTEAD UPDATE TRIGGER'T_comment_Trigger'。這是因爲該表具有級聯DELETE或UPDATE的FOREIGN KEY。**發生 – Mike

+0

@Mike - 您需要刪除* all *級聯外鍵,並在該觸發器內手動實施所有級聯。 (你仍然可以有FK,只是沒有級聯選項) –

+0

**我的表具有'級聯刪除'爲其他外鍵** – Mike