Skip to content

Commit 66af235

Browse files
committed
Refresh hierarchyid type method reference (UUF 503126)
1 parent 86269ae commit 66af235

1 file changed

Lines changed: 85 additions & 66 deletions

File tree

Lines changed: 85 additions & 66 deletions
Original file line numberDiff line numberDiff line change
@@ -1,88 +1,107 @@
11
---
2-
title: "hierarchyid (Transact-SQL)"
3-
description: "hierarchyid data type method reference"
2+
title: "Data type method reference for hierarchyid (Transact-SQL)"
3+
description: hierarchyid data type method reference
44
author: MikeRayMSFT
55
ms.author: mikeray
6-
ms.date: "07/22/2017"
6+
ms.reviewer: randolphwest
7+
ms.date: 11/03/2025
78
ms.service: sql
89
ms.subservice: t-sql
9-
ms.topic: "reference"
10+
ms.topic: reference
1011
f1_keywords:
1112
- "hierarchyid"
1213
- "hierarchyid_TSQL"
1314
helpviewer_keywords:
1415
- "Hierarchy data type"
1516
- "hierarchyid data type"
1617
dev_langs:
17-
- "TSQL"
18-
monikerRange: "=azuresqldb-current || >=sql-server-2016 || >=sql-server-linux-2017 || =azuresqldb-mi-current ||=fabric"
18+
- TSQL
19+
monikerRange: "=azuresqldb-current || >=sql-server-2016 || >=sql-server-linux-2017 || =azuresqldb-mi-current || =fabric"
1920
---
2021
# hierarchyid data type method reference
22+
2123
[!INCLUDE [SQL Server Azure SQL Database Azure SQL Managed Instance FabricSQLDB](../../includes/applies-to-version/sql-asdb-asdbmi-fabricsqldb.md)]
2224

23-
The **hierarchyid** data type is a variable length, system data type. Use **hierarchyid** to represent position in a hierarchy. A column of type **hierarchyid** does not automatically represent a tree. It is up to the application to generate and assign **hierarchyid** values in such a way that the desired relationship between rows is reflected in the values.
24-
25+
The **hierarchyid** data type is a variable length, system data type. Use **hierarchyid** to represent position in a hierarchy. A column of type **hierarchyid** doesn't automatically represent a tree. It's up to the application to generate and assign **hierarchyid** values in such a way that the desired relationship between rows is reflected in the values.
26+
2527
A value of the **hierarchyid** data type represents a position in a tree hierarchy. Values for **hierarchyid** have the following properties:
26-
27-
- Extremely compact
28-
The average number of bits that are required to represent a node in a tree with *n* nodes depends on the average fanout (the average number of children of a node). For small fanouts (0-7), the size is about 6\*logA*n* bits, where A is the average fanout. A node in an organizational hierarchy of 100,000 people with an average fanout of 6 levels takes about 38 bits. This is rounded up to 40 bits, or 5 bytes, for storage.
29-
- Comparison is in depth-first order
30-
Given two **hierarchyid** values **a** and **b**, **a<b** means a comes before b in a depth-first traversal of the tree. Indexes on **hierarchyid** data types are in depth-first order, and nodes close to each other in a depth-first traversal are stored near each other. For example, the children of a record are stored adjacent to that record. For more information, see [Hierarchical Data &#40;SQL Server&#41;](../../relational-databases/hierarchical-data-sql-server.md).
31-
- Support for arbitrary insertions and deletions
32-
By using the [GetDescendant](../../t-sql/data-types/getdescendant-database-engine.md) method, it is always possible to generate a sibling to the right of any given node, to the left of any given node, or between any two siblings. The comparison property is maintained when an arbitrary number of nodes is inserted or deleted from the hierarchy. Most insertions and deletions preserve the compactness property. However, insertions between two nodes will produce hierarchyid values with a slightly less compact representation.
33-
- The encoding used in the **hierarchyid** type is limited to 892 bytes. Consequently, nodes which have too many levels in their representation to fit into 892 bytes cannot be represented by the **hierarchyid** type.
34-
35-
The **hierarchyid** type is available to CLR clients as the **SqlHierarchyId** data type.
36-
37-
## Remarks
38-
The **hierarchyid** type logically encodes information about a single node in a hierarchy tree by encoding the path from the root of the tree to the node. Such a path is logically represented as a sequence of node labels of all children visited after the root. A slash starts the representation, and a path that only visits the root is represented by a single slash. For levels underneath the root, each label is encoded as a sequence of integers separated by dots. Comparison between children is performed by comparing the integer sequences separated by dots in dictionary order. Each level is followed by a slash. Therefore a slash separates parents from their children. For example, the following are valid **hierarchyid** paths of lengths 1, 2, 2, 3, and 3 levels respectively:
39-
40-
- /
41-
42-
- /1/
43-
44-
- /0.3.-7/
45-
46-
- /1/3/
47-
48-
- /0.1/0.2/
49-
50-
Nodes can be inserted in any location. Nodes inserted after **/1/2/** but before **/1/3/** can be represented as **/1/2.5/**. Nodes inserted before 0 have the logical representation as a negative number. For example, a node that comes before **/1/1/** can be represented as **/1/-1/**. Nodes cannot have leading zeros. For example, **/1/1.1/** is valid, but **/1/1.01/** is not valid. To prevent errors, insert nodes by using the [GetDescendant](../../t-sql/data-types/getdescendant-database-engine.md) method.
51-
28+
29+
- **Extremely compact**: The average number of bits that are required to represent a node in a tree with *n* nodes depends on the average fanout (the average number of children of a node). For small fanouts (0-7), the size is about 6 \* logA *n* bits, where A is the average fanout. A node in an organizational hierarchy of 100,000 people with an average fanout of six levels takes about 38 bits. This is rounded up to 40 bits, or 5 bytes, for storage.
30+
31+
- **Comparison is in depth-first order**: Given two **hierarchyid** values `a` and `b`, `a<b` means a comes before b in a depth-first traversal of the tree. Indexes on **hierarchyid** data types are in depth-first order, and nodes close to each other in a depth-first traversal are stored near each other. For example, the children of a record are stored adjacent to that record. For more information, see [Hierarchical data (SQL Server)](../../relational-databases/hierarchical-data-sql-server.md).
32+
33+
- **Support for arbitrary insertions and deletions**: By using the [GetDescendant](getdescendant-database-engine.md) method, it's always possible to generate a sibling to the right of any given node, to the left of any given node, or between any two siblings. The comparison property is maintained when an arbitrary number of nodes is inserted or deleted from the hierarchy. Most insertions and deletions preserve the compactness property. However, insertions between two nodes produce hierarchyid values with a slightly less compact representation.
34+
35+
- **Encoding is limited to 892 bytes:** So, nodes that have too many levels in their representation to fit into 892 bytes can't be represented by the **hierarchyid** type.
36+
37+
The **hierarchyid** type is available to common language runtime (CLR) clients as the `SqlHierarchyId` data type.
38+
39+
## Remarks
40+
41+
The **hierarchyid** type logically encodes information about a single node in a hierarchy tree by encoding the path from the root of the tree to the node. Such a path is logically represented as a sequence of node labels of all children visited after the root. A slash starts the representation, and a path that only visits the root is represented by a single slash. For levels underneath the root, each label is encoded as a sequence of integers separated by dots.
42+
43+
Comparison between children is performed by comparing the integer sequences separated by dots in dictionary order. Each level is followed by a slash. Therefore a slash separates parents from their children. For example, the following are valid **hierarchyid** paths of lengths 1, 2, 2, 3, and 3 levels respectively:
44+
45+
- `/`
46+
- `/1/`
47+
- `/0.3.-7/`
48+
- `/1/3/`
49+
- `/0.1/0.2/`
50+
51+
Nodes can be inserted in any location. Nodes inserted after `/1/2/` but before `/1/3/` can be represented as `/1/2.5/`. Nodes inserted before `0` have the logical representation as a negative number. For example, a node that comes before `/1/1/` can be represented as `/1/-1/`. Nodes can't have leading zeros. For example, `/1/1.1/` is valid, but `/1/1.01/` isn't valid. To prevent errors, insert nodes by using the [GetDescendant](getdescendant-database-engine.md) method.
52+
5253
## Data type conversion
54+
5355
The **hierarchyid** data type can be converted to other data types as follows:
54-
- Use the [ToString()](../../t-sql/data-types/tostring-database-engine.md) method to convert the **hierarchyid** value to the logical representation as a **nvarchar(4000)** data type.
55-
- Use [Read ()](../../t-sql/data-types/read-database-engine.md) and [Write ()](../../t-sql/data-types/write-database-engine.md) to convert **hierarchyid** to **varbinary**.
56-
- To transmit **hierarchyid** parameters through SOAP first cast them as strings.
57-
58-
## Upgrading databases
59-
When a database is upgraded to a newer version of [!INCLUDE [ssnoversion-md](../../includes/ssnoversion-md.md)], the new assembly and the **hierarchyid** data type will automatically be installed. Upgrade advisor rules detect any user type or assemblies with conflicting names. The upgrade advisor will advise renaming of any conflicting assembly, and either renaming any conflicting type, or using two-part names in the code to refer to that preexisting user type.
60-
61-
If a database upgrade detects a user assembly with conflicting name, it will automatically rename that assembly and put the database into suspect mode.
62-
63-
If a user type with conflicting name exists during the upgrade, no special steps are taken. After the upgrade, both the old user type, and the new system type, will exist. The user type will be available only through two-part names.
64-
65-
## Using hierarchyid columns in replicated tables
66-
Columns of type **hierarchyid** can be used on any replicated table. The requirements for your application depend on whether replication is one directional or bidirectional, and on the versions of [!INCLUDE[ssNoVersion](../../includes/ssnoversion-md.md)] that are used.
67-
56+
57+
- Use the [ToString](tostring-database-engine.md) method to convert the **hierarchyid** value to the logical representation as a **nvarchar(4000)** data type.
58+
59+
- Use [Read (Database Engine) by using CSharp](read-database-engine.md) and [Write](write-database-engine.md) to convert **hierarchyid** to **varbinary**.
60+
61+
- To transmit **hierarchyid** parameters through SOAP, first cast them as strings.
62+
63+
## Upgrade databases
64+
65+
When a database is upgraded to a newer version of [!INCLUDE [ssnoversion-md](../../includes/ssnoversion-md.md)], the new assembly and the **hierarchyid** data type are automatically installed. Upgrade advisor rules detect any user type or assemblies with conflicting names. The upgrade advisor advises renaming of any conflicting assembly, and either renaming any conflicting type, or using two-part names in the code to refer to that preexisting user type.
66+
67+
If a database upgrade detects a user assembly with conflicting name, it automatically renames that assembly and put the database into suspect mode.
68+
69+
If a user type with conflicting name exists during the upgrade, no special steps are taken. After the upgrade, both the old user type and the new system type exist. The user type is available only through two-part names.
70+
71+
<a id="using-hierarchyid-columns-in-replicated-tables"></a>
72+
73+
## Use hierarchyid columns in replicated tables
74+
75+
Columns of type **hierarchyid** can be used on any replicated table. The requirements for your application depend on whether replication is one directional or bidirectional, and on the versions of [!INCLUDE [ssNoVersion](../../includes/ssnoversion-md.md)] that are used.
76+
6877
### One-directional replication
69-
One-directional replication includes snapshot replication, transactional replication, and merge replication in which changes are not made at the Subscriber. How **hierarchyid** columns work with one directional replication depends on the version of [!INCLUDE[ssNoVersion](../../includes/ssnoversion-md.md)] the Subscriber is running.
70-
- A [!INCLUDE [ssnoversion-md](../../includes/ssnoversion-md.md)] Publisher can replicate **hierarchyid** columns to a [!INCLUDE [ssnoversion-md](../../includes/ssnoversion-md.md)] Subscriber of the same version without any special considerations.
71-
- A [!INCLUDE [ssnoversion-md](../../includes/ssnoversion-md.md)] Publisher must convert **hierarchyid** columns to replicate them to a Subscriber that is running [!INCLUDE[ssEW](../../includes/ssew-md.md)] or an earlier version of [!INCLUDE[ssNoVersion](../../includes/ssnoversion-md.md)]. [!INCLUDE[ssEW](../../includes/ssew-md.md)] and earlier versions of [!INCLUDE[ssNoVersion](../../includes/ssnoversion-md.md)] do not support **hierarchyid** columns. If you are using one of these versions, you can still replicate data to a Subscriber. To do this, you must set a schema option or the publication compatibility level (for merge replication) so the column can be converted to a compatible data type.
72-
73-
Column filtering is supported in both of these scenarios. This includes filtering out **hierarchyid** columns. Row filtering is supported as long as the filter does not include a **hierarchyid** column.
74-
78+
79+
One-directional replication includes snapshot replication, transactional replication, and merge replication in which changes aren't made at the Subscriber. How **hierarchyid** columns work with one directional replication depends on the version of [!INCLUDE [ssNoVersion](../../includes/ssnoversion-md.md)] the Subscriber is running.
80+
81+
- A [!INCLUDE [ssnoversion-md](../../includes/ssnoversion-md.md)] Publisher can replicate **hierarchyid** columns to a [!INCLUDE [ssnoversion-md](../../includes/ssnoversion-md.md)] Subscriber of the same version without any special considerations.
82+
83+
- A [!INCLUDE [ssnoversion-md](../../includes/ssnoversion-md.md)] Publisher must convert **hierarchyid** columns to replicate them to a Subscriber that's running [!INCLUDE [ssEW](../../includes/ssew-md.md)] or an earlier version of [!INCLUDE [ssNoVersion](../../includes/ssnoversion-md.md)]. [!INCLUDE [ssEW](../../includes/ssew-md.md)] and earlier versions of [!INCLUDE [ssNoVersion](../../includes/ssnoversion-md.md)] don't support **hierarchyid** columns. If you're using one of these versions, you can still replicate data to a Subscriber. To do this, you must set a schema option or the publication compatibility level (for merge replication) so the column can be converted to a compatible data type.
84+
85+
Column filtering is supported in both of these scenarios. This includes filtering out **hierarchyid** columns. Row filtering is supported as long as the filter doesn't include a **hierarchyid** column.
86+
7587
### Bi-directional replication
88+
7689
Bi-directional replication includes transactional replication with updating subscriptions, peer-to-peer transactional replication, and merge replication in which changes are made at the Subscriber. Replication lets you configure a table with **hierarchyid** columns for bi-directional replication. Note the following requirements and considerations.
77-
- The Publisher and all Subscribers must be running the same version of [!INCLUDE [sssql16-md](../../includes/sssql16-md.md)] or later.
78-
- Replication replicates the data as bytes and does not perform any validation to assure the integrity of the hierarchy.
79-
- The hierarchy of the changes that were made at the source (Subscriber or Publisher) is not maintained when they replicate to the destination.
80-
- The hash values for **hierarchyid** columns are specific to the database in which they are generated. Therefore, the same value could be generated on the Publisher and Subscriber, but it could be applied to different rows. Replication does not check for this condition, and there is no built-in way to partition **hierarchyid** column values as there is for IDENTITY columns. Applications must use constraints or other mechanisms to avoid such undetected conflicts.
81-
- It is possible that rows that are inserted on the Subscriber will be orphaned. The parent row of the inserted row might have been deleted at the Publisher. This results in an undetected conflict when the row from the Subscriber is inserted at the Publisher.
82-
- Column filters cannot filter out non-nullable **hierarchyid** columns: inserts from the Subscriber will fail because there is no default value for the **hierarchyid** column on the Publisher.
83-
- Row filtering is supported as long as the filter does not include a **hierarchyid** column.
84-
85-
## See also
86-
87-
[Hierarchical Data &#40;SQL Server&#41;](../../relational-databases/hierarchical-data-sql-server.md)
88-
90+
91+
- The Publisher and all Subscribers must be running the same version, on [!INCLUDE [sssql16-md](../../includes/sssql16-md.md)] or a later version.
92+
93+
- Replication replicates the data as bytes and doesn't perform any validation to assure the integrity of the hierarchy.
94+
95+
- The hierarchy of the changes that were made at the source (Subscriber or Publisher) isn't maintained when they replicate to the destination.
96+
97+
- The values for **hierarchyid** columns can have identical binary representations across all databases. Conflicts can occur in bi-directional replication when application logic independently generates the same **hierarchyid** for different entities. Therefore, the same value could be generated on the Publisher and Subscriber, but it could be applied to different rows. Replication doesn't check for this condition, and there's no built-in way to partition **hierarchyid** column values as there's for `IDENTITY` columns. Applications must use constraints or other mechanisms to avoid such undetected conflicts.
98+
99+
- It's possible that rows that are inserted on the Subscriber can be orphaned. The parent row of the inserted row might be deleted at the Publisher. This results in an undetected conflict when the row from the Subscriber is inserted at the Publisher.
100+
101+
- Column filters can't filter out non-nullable **hierarchyid** columns. Inserts from the Subscriber fail because there's no default value for the **hierarchyid** column on the Publisher.
102+
103+
- Row filtering is supported as long as the filter doesn't include a **hierarchyid** column.
104+
105+
## Related content
106+
107+
- [Hierarchical data (SQL Server)](../../relational-databases/hierarchical-data-sql-server.md)

0 commit comments

Comments
 (0)