5

という名前のデータベースにこの自己参照テーブルがNodesあり、組織のツリー構造を格納するために使用されます。

[Id] [int] IDENTITY(1,1) NOT NULL,
[Name] [nvarchar](max) NULL,
[ParentId] [int] NULL,
(+ other metadata columns)

そこから、HIERARCHYID を使用して、アクセス レベルなどに基づいてクエリを管理しています。私はこのためのテーブル値関数を作成しましtvf_OrgNodesた。かなり前に、SQL Server 2008 から 2014 年までテストおよび作業を行いましたが、それ以来変更されていません。ただし、パス nvarchars ("/2/10/8/") から HIERARCHYID を解析すると、次のエラーが発生し、Google で 4 つのヒット (!) しか一致しないため、何かが変更されました。

Msg 6522, Level 16, State 2, Line 26
A .NET Framework error occurred during execution of user-defined routine or aggregate "hierarchyid": 
Microsoft.SqlServer.Types.HierarchyIdException: 24000: SqlHierarchyId operation failed because HierarchyId object was constructed from an invalid binary string.

実際の HIERARCHYID の代わりに NVARCHAR のみを返すように関数を変更すると/、ルートから始まり、その後に続くパスなど、すべてのパスが正常に見えます/2/。単に選択するだけHIERARCHYID::Parse('path')でも正常に動作します。INSERT が関数の結果になるまでパスを文字列のままにして、そこでパスを解析することで、実際に関数を機能させました。しかし、残念ながら、結果のデータを同じスキーマのテーブルに挿入しようとすると、同じエラーが発生します。

質問は、これはバグですか、それとも、HIERARCHYID<->パス文字列を操作する際にこれを引き起こす可能性のある (新しい?) 落とし穴を知っている人はいますか? バイナリ文字列全体のアイデアがどこから来たのかわかりません。

これは TVF のコードです。

CREATE FUNCTION [dbo].[tvf_OrgNodes] () 
RETURNS @OrgNodes TABLE (
    OrgNode HIERARCHYID, 
    NodeId INT,
    OrgLevel INT,
    ParentNodeId INT
) AS 
BEGIN       
    WITH orgTree(OrgNode, NodeId, OrgLevel, ParentNodeId) AS (
        -- Anchor expression = root node
        SELECT    
            CAST(HIERARCHYID::GetRoot() AS varchar(180)) 
            , n.Id                            
            , 0                               
            , NULL                            
        FROM Nodes n         
        WHERE ParentId IS NULL -- Top level

        UNION ALL

        -- Recursive expression = organization tree
        SELECT
            CAST(orgTree.OrgNode + CAST(n.Id AS VARCHAR(180)) + N'/' AS VARCHAR(180))     
            , n.Id                           
            , orgTree.OrgLevel + 1           
            , n.ParentId
        FROM Nodes AS n
        JOIN orgTree 
           ON n.ParentId = orgTree.NodeId
    )
    INSERT INTO @OrgNodes
    SELECT 
        HIERARCHYID::Parse(OrgNode),
        NodeId,
        OrgLevel,
        ParentNodeId
    FROM orgTree;
    RETURN;
END

最近、lolz 用に .NET 4.53 aka 4.6 をインストールした可能性があります。ただし、reg を除いてどこにもその証拠は見つかりません: HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft.NETFramework\v4.0.30319\SKUs.NETFramework,Version=v4.5.3

4

0 に答える 0