簡體   English   中英

關於自引用表的刪除級聯

[英]On delete cascade for self-referencing table

我有一個自我引用的評論表。 我試着寫刪除級聯,但它需要一些例外

在表'注釋'上引入FOREIGN KEY約束'FK_Comments_Comments'可能會導致循環或多個級聯路徑。 指定ON DELETE NO ACTION或ON UPDATE NO ACTION,或修改其他FOREIGN KEY約束。

然后嘗試編寫一個觸發器,但它再次出現異常

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

無法刪除包含子項的行

如何為我的自引用表刪除級聯?

假設您保留了FOREIGN KEY約束,則無法在FOR DELETE觸發器中修復該問題。 活動發生FOR觸發器(也稱為AFTER觸發器)將觸發。 並且外鍵將阻止在有引用的情況下刪除行。 外鍵檢查刪除之前發生。

你需要的是一個INSTEAD OF觸發器。 您還需要記住,您當前的觸發器只是試圖處理一個“級別”的引用。 (因此,如果第3行引用第2行,第2行引用第1行,並刪除第1行,則觸發器僅嘗試刪除第2行)

所以,像:

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);

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM