Mik*_*ike 3 sql t-sql sql-server
我有一个自我引用的评论表.我试着写删除级联,但它需要一些例外
在表'注释'上引入FOREIGN KEY约束'FK_Comments_Comments'可能会导致循环或多个级联路径.指定ON DELETE NO ACTION或ON UPDATE NO ACTION,或修改其他FOREIGN KEY约束.
然后尝试编写一个触发器,但它再次出现异常
CREATE TRIGGER [dbo].[T_comment_Trigger]
ON [dbo].[Comments]
FOR DELETE
AS
DELETE FROM Comments
WHERE ParentId =(SELECT deleted.id FROM deleted)
Run Code Online (Sandbox Code Playgroud)
无法删除包含子项的行
如何为我的自引用表删除级联?
假设您保持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);
Run Code Online (Sandbox Code Playgroud)
如果存在其他(非自引用)级联外键约束,则它们都必须由此触发器中的操作替换.在这种情况下,我建议引入一个表变量来保存最终将从Comments表中删除的所有ID的列表:
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);
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
1858 次 |
| 最近记录: |