4

Web で見つけた例を使用して、GetReparentedValue を使用して子を再親化する関数を作成しました。

ただし、コードを実行すると、次のエラーが表示されます: オブジェクトに重複キーを挿入できません。

理由はわかりました (私は子供を再親化しようとしており、新しい親には既に子供がいるため、新しい親構造内の子の MAX パス (hierarchyid) を知る必要がありますが、実際にどのようになっているのかわかりません)それをするつもりです。

パス 0x58

古いパス 0x

新しいパス 0x68

SqlCommand command = new SqlCommand("UPDATE Structure SET " +
                                    "Path = " + path + ".GetReparentedValue" +
                                    "(" +
                                      oldPath + ", " + newPath +
                                    ")" +
                                    "ParentID = @id " +
                                    "WHERE Path = " + path, _connection);

子を追加するときにこれを行う必要があるため、これを上記のクエリのどこかに追加する必要があると思いましたが、どこにあるのかわかりませんpath + ".GetDescendant(" + lastChildPath + ", NULL)

データベース テーブル

StructureID   int                         Unchecked  
Path          hierarchyid                 Unchecked  
PathLevel     ([Path].[GetLevel]())       Checked  
Description   nvarchar(50)                Checked  
ParentID      int                         Checked  
ParentPath    ([Path].[GetAncestor]((1))) Checked  

誰にも何か提案はありますか?

助けてくれてありがとう:-)

クレア

4

2 に答える 2

3

これを機能させるには、いくつかの変更を加えることができます。oldPathまず、移動するノードの親を表す は必要ありません。.GetReparentedValue関数では、移動中のノードの hierarchyid を配置します。これは の値ですpath

2 番目の変更は、別の SELECT ステートメントを追加してGetDescendant関数を適用することです。SQL Server Management Studio (SSMS) で試すか、変更して SQLCommand 呼び出しに組み込むことができるサンプル スクリプトを次に示します。最初の数行 (変数宣言は代入) は、SSMS での実行専用です。最後SELECTのステートメントとUPDATEステートメントを呼び出し元のコードに転送します。

DECLARE @Path hierarchyid
DECLARE @oldPath hierarchyid
DECLARE @newPath hierarchyid
SELECT @Path=0x58, @oldPath=0x, @newPath=0x68

SELECT @newPath = @newPath.GetDescendant(MAX(Path), NULL)
FROM Structure
WHERE path.GetAncestor(1)=@newPath;

UPDATE Structure
SET Path = Path.GetReparentedValue(@Path, @newPath)
WHERE Path = @Path;

あなたのUPDATEステートメントとこのリビジョンは、1 つのノードのみを再親化します。移動ノードの子は自動的に移動しません。移動ノードの子は孤立します。

選択したノードとそのノードのすべての子孫を移動する必要がある場合は、前のステートメントの次のバリエーションを使用できます。

DECLARE @Path hierarchyid
DECLARE @oldPath hierarchyid
DECLARE @newPath hierarchyid
SELECT @Path=0x58, @oldPath=0x, @newPath=0x68

SELECT @newPath = @newPath.GetDescendant(MAX(Path), NULL)
FROM Structure
WHERE Path.GetAncestor(1) = @newPath ;

UPDATE Structure
SET Path = Path.GetReparentedValue(@Path, @newPath)
WHERE Path.IsDescendantOf(@Path) = 1;

実際、最初のスクリプトからこのスクリプトへの変更は、最後の行だけです。このテストは、 を含むPath.IsDescendantOf(@Path) = 1のすべての子孫に当てはまります。上下関係は更新後も維持されます。@Path@Path

于 2010-11-06T01:09:54.357 に答える