Предполагая, что вы держите свое ограничение 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);
Было бы очень полезно, если вы * обратили внимание * сообщения об ошибках и * скопировал свой текст в вопрос *, а не просто сказал «он принимает исключение». –
У вашего триггера есть серьезная проблема. Предполагается, что только одна строка будет удалена. Вам нужно использовать соединение для этого типа вещей. –
@Damien_The_Unbeliever Я редактирую свой вопрос – Mike