CTE with HierarchyID unexpectedly causes parsing error

So, I have this self-regulation table in my database called Nodes , used to store the tree structure of the organization:

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

And from this, I use HIERARCHYID to manage requests based on access levels, etc. I wrote a table function for this, tvf_OrgNodes , a long time ago, tested and worked on SQL Server 2008 until 2014, and since then it has not changed since it works great. Now, however, something has changed because parsing the HIERARCHYID from the nvarchars path ("/ 2/10/8 /") results in the following error, corresponding to only 4 hits (!) On Google:

 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. 

When changing the function, only return NVARCHAR instead of the actual HIERARCHYID, all the paths look fine, starting with / for the root, and then /2/ , etc. etc. Just selecting HIERARCHYID::Parse('path') also works great. I actually got the function by working, leaving the paths as strings until the INSERT returns to the result of the function by analyzing the paths there. But alas, I get the same error when I try to insert reusable data into a table of the same schema.

So the question is: Is this a bug, or does anyone know of any (new?) Traps when working with HIERARCHYIDs ↔ Path strings that can cause this? I don’t understand where the whole idea of ​​the binary string came from.

This is the TVF code:

 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 

Perhaps I recently installed .NET 4.53 aka 4.6 for lolz. I can not find much evidence of this anywhere except in reg, however: HKEY_LOCAL_MACHINE \ SOFTWARE \ Microsoft.NETFramework \ v4.0.30319 \ SKUs.NETFramework, Version = v4.5.3

+5
source share

Source: https://habr.com/ru/post/1209332/


All Articles