Hvis du antager, at du beholder din FOREIGN KEY
begrænsning på plads, kan du ikke løse problemet i en FOR DELETE
udløser. FOR
udløsere (også kendt som AFTER
udløsere) skyder efter aktiviteten har fundet sted. Og en fremmednøgle vil forhindre en række fra at blive slettet, hvis den har referencer. Fremmednøgletjek finder sted før sletning.
Det du har brug for er en INSTEAD OF
udløser. Du skal også huske på, at din nuværende trigger kun forsøgte at håndtere ét "niveau" af referencer. (Så hvis række 3 refererer til række 2 og række 2 refererer til række 1, og du sletter række 1, forsøgte din trigger kun at fjerne række 2)
Altså noget som:
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);
Hvis der er andre (ikke-selv-refererende) kaskadende fremmednøgle-begrænsninger, skal de alle erstattes af handlinger i denne trigger. I et sådant tilfælde vil jeg anbefale at introducere en tabelvariabel til at indeholde listen over alle id'er, der til sidst vil blive slettet fra Comments
tabel:
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);