I have a hierarchyid with the value '/1/'. When I insert it into the SQL Database it's stored as 0x58.
Here is my table:
CREATE TABLE [dbo].[Category](
[CategoryId] [int] IDENTITY(1,1) NOT NULL,
[Name] [nvarchar](max) NULL,
[HierarchyDescription] [hierarchyid] NULL,
CONSTRAINT [PK_Category] PRIMARY KEY CLUSTERED
(
[CategoryId] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON, OPTIMIZE_FOR_SEQUENTIAL_KEY = OFF) ON [PRIMARY]
) ON [PRIMARY] TEXTIMAGE_ON [PRIMARY]
And here is how I do it:
INSERT INTO [dbo].[Category] ([Name] ,[HierarchyDescription])
VALUES ('CAT1', '/1/');
How is the value 0x58 obtained?
I tried doing this in C#
Encoding.ASCII.GetBytes("/1/");
And I got the value 0x2F312F (47 49 47) in Hex.
HierarchyId is documented as Extremely compact
So it is clear that it can manage to fit more than one level in a byte.
The internal format isn't documented but someone has previously investigated this (way back machine link as the original page didn't load when I looked at it).
Disclaimer: The source in itself is non authoritative and just deduced from inspection of values and I may have introduced further errors in the below!
The below gives some fairly simple examples
Results
The binary representation of
0x58is01011000but trailing zeroes should be ignored so we only have 5 bits to care about.01011.The linked article supposes that the initial prefix
01is reserved for components/0/.../3/so it knows it only has to read three more bits for this component. The next two bits are for the value itself and the final bit is1because this is not a dotted component.The representation of
/1/1/just concatenates two of these together.The representation of
1.1adds1to01011to get01100then concatenates a01011onto the end of that./98/is more complicated. This gives a bit string of111000000010010101.The linked article indicates that the range
/80/through/1103/will have the prefix1110and be in the form1110aaa0zzz0y1xxx1aaa=000(decimal0)zzz=001(decimal1)y=0(decimal0)xxx=010(decimal2)1x + 8y + 16z + 80=2 + 0 + 16 + 80=98There is also the possibility that the component may have a negative number. See the linked article if interested in that!