2009-07-29 15 views

Odpowiedz

5

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.

3

Będziemy chcieli przyjrzeć się metodzie IsDescendantOf w T-SQL. Coś takiego:

DECLARE @ParentNodeHID hierarchyid SET @ParentNodeHID = [węzeł chcesz rozpocząć usuwanie at]

DELETE HierarchyTable GDZIE NodeHID.IsDescendantOf (@ParentNodeHID) = 1

(HierarchyTable = Tabela, w której przechowywana jest twoja hierarchia)

** Należy pamiętać, że z tą metodą węzeł jest uważany za dziecko samego w sobie. Tak więc, cokolwiek przekażesz do @ParentNodeHID, spełni warunki klauzuli WHERE.

Spójrz na artykuł BOL: MS-help: //MS.SQLCC.v10/MS.SQLSVR.v10.en/s10de_6tsql/html/edc80444-b697-410f-9419-0f63c9b5618d.htm

Powiązane problemy