1

我有下表:

MyTree(IDNode, IDRootNode, IDParentNode, Left, Right, Depth, ...)

IDNode 是标识节点的主键。IDRootNode 是根节点。IDParentNode 是节点的父节点。Left 和 Right 是节点的位置。对删除不重要。

我看到下面的代码是一个触发器,它可以从自引用表中删除寄存器:

CREATE TRIGGER MyTable_OnDelete ON MyTable
INSTEAD OF DELETE
AS 
BEGIN

  SET NOCOUNT ON;

  DELETE FROM mt
  FROM   deleted AS D
  JOIN   MyTable AS mt
  ON     d.Id = mt.ParentId

  DELETE FROM mt
  FROM   deleted AS D
  JOIN   MyTable AS mt
  ON     d.Id = mt.Id

END

如果我没记错的话,首先删除我要删除的节点的子节点,然后再删除该节点。但是如果一个孩子有孩子,也被删除或者只删除节点的孩子而不是孩子的孩子?

使用递归 CTE 会怎么样?

谢谢。

4

2 回答 2

2

如果树中的每个节点的 IDRootNode 列都填充了该节点所属树的 id,则可以使用以下 SQL 删除树:

DELETE MyTable WHERE IDRootNode = @RootNodeId
于 2013-04-11T20:36:51.200 回答
2

您可以使用递归 CTE 来做到这一点,如下所示:

;WITH cte AS (
    SELECT  IDNode
    FROM    Deleted
    UNION ALL
    SELECT  IDNode
    FROM    MyTree t
            JOIN cte c ON t.IDParentNode = c.IDNode
) 
DELETE  t
FROM    MyTree t
        JOIN cte c ON t.IDNode = c.IDNode;

更好的是,使用 HierarchyId(如果在 SQL Server 2008 上)!

于 2013-04-11T20:39:00.773 回答