триггер-решение будет:
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, он может очень легко осилить ваши дочерние записи, не зная до тех пор, пока не станет слишком поздно.