0

次のようにストアド プロシージャを作成しました。

CREATE PROCEDURE [SPNAME] 
    @UserCode INT, 
    @ReportsTo INT
AS
BEGIN
    SET NOCOUNT ON;
    DECLARE @HierarchyId HIERARCHYID
    DECLARE @NewParentHierarchyId HIERARCHYID
    DECLARE @OldParentHierarchyId HIERARCHYID
    SELECT  @HierarchyId = [Hierarchy]
    FROM    [aspnet_Users]
    WHERE   [UserCode] = @UserCode
    SELECT  @OldParentHierarchyId = [Hierarchy].GetAncestor(1)
    FROM    [aspnet_Users]
    WHERE   [UserCode] = @UserCode
    PRINT N'Old Root: ' + @OldParentHierarchyId.ToString()
    SET TRANSACTION ISOLATION LEVEL SERIALIZABLE
    BEGIN TRANSACTION
        SELECT  @NewParentHierarchyId = [Hierarchy]
        FROM    [aspnet_Users]
        WHERE   [UserCode] = @ReportsTo
        PRINT N'New Root: ' + @NewParentHierarchyId.ToString()
        PRINT N'Old HierarchyId: ' + @HierarchyId.ToString()
        SELECT  @HierarchyId = @NewParentHierarchyId.GetDescendant(MAX([Hierarchy]), NULL)
        FROM    [aspnet_Users]
        WHERE   [Hierarchy].GetAncestor(1) = @NewParentHierarchyId
        PRINT N'New HierarchyId: ' + @HierarchyId.ToString()
        UPDATE  [aspnet_Users]
        SET     [Hierarchy] = @HierarchyId.GetReparentedValue(@OldParentHierarchyId, @NewParentHierarchyId)
        WHERE   [Hierarchy].IsDescendantOf(@OldParentHierarchyId) = 1
    COMMIT TRANSACTION
END

次のような階層データがあります。

  imirza10 (UserCode 1)
  -adil    (UserCode 3)
  --arif   (UserCode 5)
  ---saqib (UserCode 6)
  -farhan  (UserCode 4)

上記のストアド プロシージャは、arif を adil から farhan に移動するためのものでした。

ステートメントでspを実行したとき:

[aspnet_Users_ChangeHierarchy] 5, 4

SSMSのメッセージタブで次のようになります。

Old Root: /1/1/
New Root: /1/2/
Old HierarchyId: /1/1/1/
New HierarchyId: /1/2/1/

メッセージ 6522、レベル 16、状態 2、プロシージャ aspnet_Users_ChangeHierarchy、行 48
ユーザー定義ルーチンまたは集計 "hierarchyid" の実行中に .NET Framework エラーが発生しました:
Microsoft.SqlServer.Types.HierarchyIdException: 24009: SqlHierarchyId.GetReparentedValue が失敗したため、'oldRoot ' は 'this' の祖先ノードではありませんでした。「oldRoot」は「/1/1/」で、「this」は「/1/2/1/」でした。
Microsoft.SqlServer.Types.HierarchyIdException:
Microsoft.SqlServer.Types.SqlHierarchyId.GetReparentedValue (SqlHierarchyId oldRoot、SqlHierarchyId newRoot) で

これについて助けが必要です。

4

1 に答える 1

0

さらにテストを行わないと、クエリに次の問題が見られます。

  1. エラー メッセージが示すのは、 は の祖先ではないため@HierarchyId、 から@OldParentHierarchyIdに親を変更できないということです(新しいパスとして計算されています)。@NewParentHierarchyId@HierarchyId@OldParentHierarchyId
  2. @HierarchyId.GetReparentedValue実際の値の代わりに新しい位置を計算するために使用します。これにより、すべての行で同じ結果が得られます。
  3. @OldParentHierarchyIdアップデートから除外する必要があります。

UPDATE クエリは次のようになります。

UPDATE [aspnet_Users]
SET    [Hierarchy] = [Hierarchy].GetReparentedValue(@OldParentHierarchyId, @NewParentHierarchyId)
WHERE  [Hierarchy].IsDescendantOf(@OldParentHierarchyId) = 1 AND [Hierarchy] <> @OldParentHierarchyId

PS:この質問に遅れていることは知っていますが、とにかく誰かを助けるかもしれません.

于 2015-06-08T17:42:28.013 に答える