我有下表:
MyTree(IDNode, IDRootNode, IDParentNode, Left, Right, Depth, ...)
IDNode是识别节点的主键。 IDRootNode是根节点。 IDParentNode是节点的父节点。 左和右是节点的位置。对于删除并不重要。
我看到以下代码是一个触发器,它允许从自引用表中删除寄存器:
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
如果我没错,首先删除我要删除的节点的子节点,然后删除该节点。但是如果孩子有孩子,也会被删除或只删除节点的孩子而不是孩子的孩子?
然后用recrsive CTE怎么样?
感谢。
答案 0 :(得分:2)
如果树中的每个节点都使用节点所属树的id填充了IDRootNode列,则可以使用以下SQL删除树:
DELETE MyTable WHERE IDRootNode = @RootNodeId
答案 1 :(得分: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上)!
答案 2 :(得分:0)
Necromancing。
这里热闹的解决方案。
对于那些有任何理智的人,你应该知道删除级联存在。
示例:
FOREIGN KEY (parent_id)
REFERENCES table_name(id) ON DELETE CASCADE
然后你可以这样做:
DELETE FROM table_name WHERE id = @root_id
它将自动将删除级联到树下 不需要层次结构或CTE,也不需要任何递归。