我没有太多使用 HierarchyID,所以我有点不确定。如果我的表有 HierarchyID,如何执行级联删除?(即删除“父”时删除所有“子”)
我假设我必须使用 CTE 和 HierarchyID 函数,但不知道如何去做......
我没有太多使用 HierarchyID,所以我有点不确定。如果我的表有 HierarchyID,如何执行级联删除?(即删除“父”时删除所有“子”)
我假设我必须使用 CTE 和 HierarchyID 函数,但不知道如何去做......
基于触发器的解决方案是:
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
It seems a lot simpler at first, but keep in mind that people have to remember to use this. If you don't have the trigger, and somebody does a direct DELETE
on the hierarchy table instead of going through the SP, it could very easily orphan your child records without anyone knowing until it's too late.
你会想看看 T-SQL 中的 IsDescendantOf 方法。像这样的东西:
DECLARE @ParentNodeHID hierarchyid SET @ParentNodeHID = [您要开始删除的节点]
DELETE HierarchyTable WHERE 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