SQL Server HierarchyId:移动子树问题

时间:2013-03-20 08:39:15

标签: sql-server debugging stored-procedures

我创建了一个存储过程,如下所示:

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/
  

Msg 6522,Level 16,State 2,Procedure aspnet_Users_ChangeHierarchy,Line 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)

需要帮助。

1 个答案:

答案 0 :(得分:0)

在没有任何进一步测试的情况下,我在您的查询中看到以下问题:

  1. 错误消息告诉您的是,您无法将@HierarchyId@OldParentHierarchyId重新定位到@NewParentHierarchyId因为@HierarchyId不是@OldParentHierarchyId的祖先(您有把它计算为新路径。)
  2. 您使用@HierarchyId.GetReparentedValue来计算新位置而不是实际值。这将为所有行提供相同的结果。
  3. 您需要从更新中排除@OldParentHierarchyId
  4. UPDATE查询应如下所示:

    UPDATE [aspnet_Users]
    SET    [Hierarchy] = [Hierarchy].GetReparentedValue(@OldParentHierarchyId, @NewParentHierarchyId)
    WHERE  [Hierarchy].IsDescendantOf(@OldParentHierarchyId) = 1 AND [Hierarchy] <> @OldParentHierarchyId
    
    PS:我知道我在这个问题上迟到了,但无论如何它可能对某人有帮助。