私は 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
最初はずっと簡単に思えますが、人々はこれを使用することを忘れないようにする必要があることに注意してください。トリガーがなく、誰かがDELETE
SPを経由せずに階層テーブルを直接実行すると、手遅れになるまで誰も知らなくても、子のレコードが非常に簡単に孤立する可能性があります。
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