On delete cascade for self-referencing table

前端 未结 1 1105
情书的邮戳
情书的邮戳 2021-01-06 04:02

I have a comment table that is self-referencing. I tried to write on delete cascade but it take some exception

Introducing FOREIGN KEY constraint \'F

相关标签:
1条回答
  • 2021-01-06 04:29

    Assuming you're keeping your FOREIGN KEY constraint in place, you cannot fix the issue in a FOR DELETE trigger. FOR triggers (also known as AFTER triggers) fire after the activity has taken place. And a foreign key will prevent a row from being deleted if it has references. Foreign key checks occur before deletion.

    What you need is an INSTEAD OF trigger. You also need to bear in mind that your current trigger only tried to deal with one "level" of referencing. (So, if row 3 references row 2 and row 2 references row 1, and you delete row 1, your trigger only tried to remove row 2)

    So, something like:

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

    If there are other (non-self-referencing) cascading foreign key constraints, they all have to be replaced by actions in this trigger. In such a case, I'd recommend introducing a table variable to hold the list of all IDs that will eventually be deleted from the Comments table:

    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 讨论(0)
提交回复
热议问题