我没有太多使用HierarchyID,所以我有点不确定。如果我的表有HierarchyID,我该如何执行级联删除? (即删除'父母'时删除所有'孩子')
我假设我必须使用CTE和HierarchyID函数,但不知道如何去做...
答案 0 :(得分:6)
基于触发器的解决方案是:
CREATE TRIGGER tr_Hierarchy_DeleteChildren
ON Hierarchy
FOR DELETE
AS
DELETE FROM Hierarchy
WHERE ID IN
(
SELECT DISTINCT h.ID
FROM deleted d
INNER JOIN Hierarchy h
ON h.ObjectNode.IsDescendantOf(d.ObjectNode) = 1
EXCEPT
SELECT ID
FROM deleted
)
EXCEPT
确保我们不会以无限递归循环结束。在我自己的实现中,我实际上在触发器正在运行的上下文信息中设置了一个标志,然后在触发器的开头检查此标志并在标志已经设置的情况下提前返回。这不是必需的,但性能稍好一些。
或者,如果您不想使用触发器,可以将以下逻辑放在存储过程中:
CREATE PROCEDURE DeleteHierarchyTree
@ParentID hierarchyid
AS
DELETE FROM Hierarchy
WHERE ID.IsDescendantOf(@ParentID) = 1
一开始似乎要简单得多,但请记住,人们必须记住才能使用它。如果您没有触发器,并且有人在层次结构表上直接DELETE
而不是通过SP,那么在没有任何人知道的情况下,它很容易孤立您的子记录,直到为时已晚。
答案 1 :(得分:4)
您需要查看T-SQL中的IsDescendantOf方法。像这样:
DECLARE @ParentNodeHID hierarchyid SET @ParentNodeHID = [您想要开始删除的节点]
DELETE HierarchyTable 在哪里NodeHID.IsDescendantOf(@ ParentNodeHID)= 1
(HierarchyTable =存储层次结构的表)
**请记住,使用此方法,节点被视为自身的子节点。因此,无论您传入@ParentNodeHID,都将满足WHERE子句条件。
看一下BOL文章:ms-help://MS.SQLCC.v10/MS.SQLSVR.v10.en/s10de_6tsql/html/edc80444-b697-410f-9419-0f63c9b5618d.htm