使用CTE在自引用表中递归删除行。这个过程是如何进行的?

时间:2017-09-12 21:50:52

标签: sql-server triggers recursive-query sql-cte

我正在处理一个辅助项目,并且为了在自引用表中删除一行及其所有后代,我使用了 触发器内的这种递归CTE:

CREATE TRIGGER dbo.tr_Comment_Delete
    ON dbo.Comment INSTEAD OF DELETE
AS
    ;WITH IDs AS (
       SELECT id FROM DELETED
       UNION ALL
       SELECT c.id
       FROM Comment AS c INNER JOIN IDs AS i 
        ON c.parent_comment_id = i.id
    )
    DELETE FROM Comment
    WHERE id IN (SELECT id FROM IDs);
GO

这是自引用表

enter image description here

虽然我的代码按预期运行,但这是您执行某些操作的情况之一,但您并不十分确定 它是如何工作的。

更准确地说,我想知道的是通过使用这种递归CTE(ID),我能够避免引用完整性错误 当我尝试删除有孩子评论的评论时?

删除评论的过程/顺序是什么?

以此评论层次结构为例:

3-> 8-> 13 

这里,id 3的注释是根注释。评论8是对评论3的回复,就像评论13是对评论8的回复一样。

删除过程实际上是如何进行的?

P.S。我尝试添加一个表,我在计算时插入了ID。不幸的是,我无法理解它。 这些是这样的表的结果:

id  ins-date
3   2017-09-12 11:48:38.037
8   2017-09-12 11:48:38.037
13  2017-09-12 11:48:38.037
13  2017-09-12 11:48:38.037
8   2017-09-12 11:48:38.037
13  2017-09-12 11:48:38.037

1 个答案:

答案 0 :(得分:1)

我认为你看到它不存在的复杂性。

你的错误是:

  

在自引用CTE中递归删除行

没有递归DELETE这样的东西。只有SELECT可以。

所以处理很简单:

  1. 使用recurcive CTE计算SELECT中要删除的所有行

  2. DELETE他们只需一次操作

  3. 这就是全部