sql >> Base de Datos >  >> RDS >> Sqlserver

Al eliminar la cascada para la tabla autorreferencial

Suponiendo que conservas tu FOREIGN KEY restricción en su lugar, no puede solucionar el problema en un FOR DELETE generar. FOR disparadores (también conocidos como AFTER disparadores) disparar después se ha realizado la actividad. Y una clave foránea prevendrá una fila se elimine si tiene referencias. Las comprobaciones de claves externas se producen antes eliminación.

Lo que necesitas es un INSTEAD OF generar. También debe tener en cuenta que su disparador actual solo trató de lidiar con un "nivel" de referencia. (Entonces, si la fila 3 hace referencia a la fila 2 y la fila 2 hace referencia a la fila 1, y elimina la fila 1, su disparador solo intentó eliminar la fila 2)

Entonces, algo como:

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

Si hay otras restricciones de clave externa en cascada (que no hacen referencia a sí mismas), todas deben reemplazarse por acciones en este disparador. En tal caso, recomendaría introducir una variable de tabla para contener la lista de todas las ID que eventualmente se eliminarán de los Comments tabla:

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