Ако приемем, че запазвате своя 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
таблица:
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);