rozwiązanie spust oparte byłoby:
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
zapewnia, że nie skończy się w nieskończonej pętli rekurencyjnej. W moich własnych implementacjach ustawiam flagę w informacjach kontekstowych, w której uruchomiony jest wyzwalacz, a następnie zaznacz tę flagę na początku wyzwalacza i wróć wcześniej, jeśli flaga jest już ustawiona. Nie jest to konieczne, ale jest nieco lepsze pod względem wydajności.
Ewentualnie, jeśli nie chcesz używać spust, można umieścić następującą logikę w procedurę przechowywaną:
CREATE PROCEDURE DeleteHierarchyTree
@ParentID hierarchyid
AS
DELETE FROM Hierarchy
WHERE ID.IsDescendantOf(@ParentID) = 1
Wydaje się dużo prostsze w pierwszym, ale należy pamiętać, że ludzie mają do zapamiętaj, aby użyć tego. Jeśli nie masz wyzwalacza, a ktoś robi bezpośrednio DELETE
w tabeli hierarchii zamiast przechodzić przez SP, może bardzo łatwo osierocić twoje rekordy podrzędne bez wiedzy kogokolwiek, dopóki nie będzie za późno.