我正在制作一个完整的堆栈Web应用程序,并且正在尝试尽可能多地在数据库中编写逻辑。
我有一个像
这样的评论系统 1
/ \
2 3
/ \
4 5
我代表
Comments
===============
id | ...
---------------
1 | ...
2 | ...
3 | ...
4 | ...
5 | ...
CommentTree
===================================
id | ancestor | descendant | ...
-----------------------------------
1 | 1 | 1 | ...
2 | 1 | 2 | ...
3 | 1 | 3 | ...
4 | 1 | 4 | ...
5 | 1 | 5 | ...
6 | 2 | 2 | ...
7 | 2 | 4 | ...
8 | 2 | 5 | ...
9 | 3 | 3 | ...
10 | 4 | 4 | ...
11 | 5 | 5 | ...
我想知道如何进行设置,以便在删除评论时删除所有后代。我知道如何设置它以在删除祖先时删除对祖先 - 后代关系的引用:
FOREIGN KEY (ancestor) REFERENCES Comments(id) ON DELETE CASCADE
但是如何让 操作触发后续评论也被删除?
换句话说,发生以下事件链
我已经完成了第1步和第2步,但我怎么能在那里工作第3步?我是否必须编写一个在删除每个树元素时触发的过程?你能告诉我一个这样看的例子吗?
答案 0 :(得分:2)
我认为不可能实现使用约束。这是因为会发生循环。您可以尝试使用触发器来实现它,但我不推荐它,因为可见性非常低(我甚至不确定它是否可行)。
我建议您在删除评论时调用的存储过程。它更容易维护,可见性更好。
create procedure DeleteComment(
@CommentID int
)
as
declare
@CommentToDelete TABLE (id int);
begin
-- save comments for deletion
insert into @CommentToDelete
select descendant from CommentTree
where ancestor = @CommentID;
-- delete relation from tree
with tree (commentTreeID, ancestor, descendant , path, src) as
(
select id, ancestor, descendant , cast ( '-'+ cast(id as varchar(2000)) +'-' as varchar(2000)) , 0from
CommentTree ct
where ct.ancestor = @CommentID
union all
select CT.Id, CT.ancestor, CT.descendant ,cast( t.path + '-' + cast(id as varchar(2000)) +'-' as varchar(2000)), 1
from tree t
join CommentTree CT
on CT.ancestor = t.descendant and
CHARINDEX (cast( '-' + cast(id as varchar(2000)) +'-' as varchar(2000)), t.path) = 0 and
t.src != 2
union all
select CT.Id, CT.descendant, CT.ancestor ,cast( t.path + '-' + cast(id as varchar(2000)) +'-' as varchar(2000)), 2
from tree t
join CommentTree CT
on CT.descendant = t.descendant and
CHARINDEX(cast( '-' + cast(id as varchar(2000)) +'-' as varchar(2000)), t.path) =0 and
t.src != 2
)
delete CT
from CommentTree CT
join tree t
on t.commentTreeID = CT.ID;
-- now we can delete comments
delete Comments
where id in (select id from @CommentToDelete);
end;
当我们上升时,我们不想再次上升或下跌=> t.src != 2
让它成为现实。
CHARINDEX (... )
保护我们免受循环。