2009-07-29 5 views

risposta

5

La soluzione basata su trigger potrebbe essere:

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 
    ) 

Il EXCEPT assicura che noi non finire in un ciclo ricorsivo infinito. Nelle mie implementazioni, ho effettivamente impostato un flag nelle informazioni di contesto che il trigger è in esecuzione, quindi spunta questo flag all'inizio del trigger e ritorni presto se il flag è già impostato. Questo non è necessario, ma è leggermente migliore per le prestazioni.

In alternativa, se non si desidera utilizzare un trigger, si potrebbe mettere la seguente logica in una stored procedure:

CREATE PROCEDURE DeleteHierarchyTree 
    @ParentID hierarchyid 
AS 
DELETE FROM Hierarchy 
WHERE ID.IsDescendantOf(@ParentID) = 1 

Sembra molto più semplice in un primo momento, ma di tenere presente che le persone hanno a per ricordare questo. Se non si ha il trigger, e qualcuno fa direttamente un DELETE nella tabella della gerarchia invece di passare attraverso l'SP, potrebbe facilmente rendere orfano il proprio figlio senza che nessuno lo sappia fino a quando non è troppo tardi.

3

Vorrete dare un'occhiata al metodo IsDescendantOf in T-SQL. Qualcosa di simile a questo:

DECLARE @ParentNodeHID hierarchyid SET @ParentNodeHID = [il nodo che si desidera iniziare la cancellazione at]

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

(HierarchyTable = Tabella in cui è memorizzata la gerarchia)

** Tenere presente che con questo metodo, un nodo è considerato un figlio di se stesso. Quindi, qualunque cosa tu passi nel @ParentNodeHID soddisferà le condizioni della clausola WHERE.

Date un'occhiata a questo articolo BOL: ms-help: //MS.SQLCC.v10/MS.SQLSVR.v10.en/s10de_6tsql/html/edc80444-b697-410f-9419-0f63c9b5618d.htm