Site sponsored by: Idera Try Idera’s new SQL admin toolset
SQL Server Performance

  • Home
  • Articles
  • Forums
  • Tips
  • Quiz
  • FAQ's
  • Blogs
  • Software
  • Books
  • About Us
RSS Feeds
Sign in | Join


Article Topics

All Articles
Performance Tuning
Audit
Business Intelligence
Clustering
Reporting Services
Developer
General DBA
ASP.NET / ADO.NET

Write for Us

Share you SQL Server knowledge with others and raise your profile in the community More...
Latest Articles

Capture DDL Changes using Change Data Capture with SQL Server 2008 ...
Business Intelligence in Collaborative Planning, Forecasting and Replenishment
Inside SQL Server Cluster Setup and Troubleshooting Techniques - Part I ...
Configure and Manage Policy Based Management in SQL Server 2008 ...

More     
 
Latest FAQ's

Cannot Start SQL Server Service
Users are able to connect to report manager but not able ...
Errors when SQL Server Snapshot Replication is Running
How to Display Server Name or IP Address in a Reporting ...

More     
   
Latest Software Reviews

Spotlight on ApexSQL Doc 2008
ApexSQL Enforce
Embarcadero Change Manager
SQL Server DBA Dashboard

More     

articles >> developer >> New Data Types in SQL Server 2008 ...

New Data Types in SQL Server 2008 Part 2

By : Dinesh Asanka
Jan 31, 2008

Page 2 / 2



HierarchyID in SQL Server 2008
Now let see how we can do this with the HierarchyID in SQL Server 2008.

First we will create a table using the new data type named HierarchyID.

CREATE TABLE [dbo].[Employee](
    
[ID] [int] IDENTITY(1,1) NOT NULL,
    [Name] [varchar](40) NULL,
    [Designation] [varchar](40) NULL,
    
[HierarchyID] [hierarchyid] NULL)

The HierarchyID data type is a variable length, system data type. 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.

First we need to insert our root record which is the CEO of the company who is Mathew.

INSERT INTO [dbo].[Employee]
([Name]
,[Designation]
,[HierarchyID])
VALUES                     
('Mathew'
,'CEO'
,hierarchyid::GetRoot())

The GetRoot() method will return the root of the hierarchy tree. It will return the data type HierarchyID.

Next task is to insert the next level of employees. The next level employees are Andy, Lessa and Tony. When we do this a new method called GetDescendant is used. The GetDescendant method is very useful to get the descendant of a given node. The syntax for the method is parent.GetDescendant (child1, child2 ). The following table gives you the output that you will get depending on the parameters that you use.

Parent

Child1

Child2

Return

NULL

 

 

NULL

Not NULL

NULL

NULL

Child of parent

Not NULL

Not NULL

NULL

Child of parent greater than Child1

Not NULL

NULL

Not NULL

Child of parent less than Child2

Not NULL

Not NULL

Not NULL

Child of parent greater than child1 and less than child2.

Not NULL

Child1 or Child2 is not NULL but is not a child of parent

Exception

Not NULL

Child1 >= Child2

Exception


DECLARE @Manager hierarchyid                     
SELECT @Manager = hierarchyid::GetRoot() FROM dbo.Employee
INSERT INTO [dbo].[Employee]
([Name]
,[Designation]
,[HierarchyID])
VALUES
('Andy'
,'Chief Marketing Officer'
,@Manager.GetDescendant(NULL,NULL))

The above code will insert Andy into the table with HierarchyID of /1/ .

DECLARE @Manager hierarchyid                     
DECLARE @FirstChild hierarchyid                    
SELECT @Manager = hierarchyid::GetRoot() FROM dbo.Employee
SELECT @FirstChild =@Manager.GetDescendant(NULL,NULL)

INSERT INTO [dbo].[Employee]
([Name]
 
,[Designation]
,[HierarchyID])
VALUES
('Lessa'       
,'Finance Controller'
,@Manager.GetDescendant(@FirstChild,NULL))

The above code will insert Lessa into the table with a HierarchyID of /2/. @Manager.GetDescendant(@FirstChild,NULL) will return /2/ as @FirstChild is /1/

DECLARE @Manager hierarchyid                     
DECLARE @FirstChild hierarchyid                    
DECLARE @SecondChild hierarchyid                               

SELECT @Manager = hierarchyid::GetRoot() FROM dbo.Employee
SELECT @FirstChild =@Manager.GetDescendant(NULL,NULL)
SELECT @SecondChild =@Manager.GetDescendant(@FirstChild,NULL)

INSERT INTO [dbo].[Employee]
([Name]
,[Designation]
,[HierarchyID])
VALUES
('Tony'        
,'CIO'
,@Manager.GetDescendant(@SecondChild,NULL))

After inserting the data, your employee table will look like the following:



This illustarted how the HierarchyID column data is inserted.

Using Stored Procedure
Even though the previous examples show how to insert data, in the real world example we would add employee using a stored procedure by passing the relevant parameters. The parameters will be Employee Name, the designation and the Manager’s employee ID.

The Following stored procedure will add an employee.

CREATE PROCEDURE [dbo].[InsertEmployee]
(@ManagerID int,
@EmpName varchar(50),
@Designation varchar(100)
)
AS
BEGIN
DECLARE @varlastChild VARCHAR(10)
,@hieManagrID HIERARCHYID
,@LastChild HIERARCHYID
---- Get the hierarchyid of the manager
SELECT @hieManagrID = HIERARCHYID
FROM Employee
WHERE ID = @ManagerID

Set @varlastChild = @hieManagrID.ToString()

---- Get the MAX hierarchyid of the next level where the employee should be in
SELECT @LastChild = MAX(HIERARCHYID)
FROM Employee
WHERE hierarchyid.ToString() LIKE @varLastChild +'[0-9]/'

INSERT INTO Employee
(Name,Designation,hierarchyid)
VALUES
(@EmpName,@Designation,@hieManagrID.GetDescendant(@LastChild,NULL))

END ;

The new method ToString() is used in the above script. This method is useful to get the string representation of the HierarchyID. The method returns a string that is a nvarchar(4000) data type. The syntax of this method is node.ToString ( ). The Parse() method is the method used to convert string into HierarchyID which is the opposite of the ToString() method.

If you run the following script, you will have a record with hierachyid of /3/1/3/.

EXEC [dbo].[InsertEmployee]
    

@ManagerID = 9,
    
@EmpName = 'Sandrina',
    
@Designation = 'QA '

Data Retrieval

The next step is to retrieve your data. Let's see how we can get the results we got from the SQL Server 2005 by using CTE.

SELECT ID
    ,Name
    ,Designation
    , Hierarchyid.GetLevel() as Level
    ,(Select ID FRom Employee Where Hierarchyid = e.Hierarchyid.GetAncestor(1)) As ManagerID
FROM employee e

In the above script we are using two new methods named, GetLevel and GetAncestor. The GetLevel() method is useful to find the Level of the current node. This method will return an integer that represents the depth of this node in the current tree. The GetAncestor() method will give you the hierarchyID of the parent node.

However, in the case of inserting a new level to a table with a HierarchyID column in not easy. You have to change all the parents using a Reparent() method. This is a very useful method which helps you to reparent a node i.e. suppose if we want to align an existing node to a new parent or any other existing parent then this method is very useful.

Syntax: node.Reparent ( oldRoot, newRoot )

Use of HierarchyID
Apart from saving organizational structure, there are several other structures that you can save with using hierarchyid in SQL Server 2008.

  • A file system which has directory hierarchy
  • A set of tasks in a project in which one task may be divided into several sub tasks.
  • Goods which consists of other goods and raw materials.

Issues of HierarchyID Data Type

  • There is no straight forward way of finding the next available Hierarchy ID. You need to find the maximum current hierarchy and then get the next available hierarchy.
  • Reparent is easy and you have to reassign all the relevant records.
  • You cannot have two roots in one table. Root will be displayed as /, therefore you cannot have two roots. However there are two ways to tackle this issue.
    • You can have an additional column. In the case of our previous example, you can have another column saying OrganizationID. So OrganizationID and HierarchyID make a unique key. 
    • Another way of doing this is having one root and the next level should be assigned to the organization.

However, it would be better if we could assign the root with some value, so that we can have any number of roots in the table.


<< Prev Page         








Home | Peformance Articles | Audit Articles | Business Intelligence Articles | Clustering Articles | Developer Articles | Reporting Services Articles | DBA Articles | ASP.NET / ADO.NET Articles | DBA FAQ's | Developer Peformance FAQ's | DBA Peformance FAQ's | Developer FAQ's | Clustering FAQ's | Error Messages | Audit Tool Reviews | Backup Tool Reviews | Coding Tool Reviews | Compare Tool Reviews | Documentation Tool Reviews | Design Tool Reviews | Monitoring Tool Reviews | Log Tool Reviews | Reporting Tool Reviews | Clustering Tool Reviews | Security Tool Reviews | Change Management Tool Reviews | Remote Access Tool Reviews | Book Reviews | Security Tool Reviews | QDPMA Performance Tuning | ADO.NET / ASP.NET | Administration | Analysis/OLAP Services | Application Development | Configuration | Components | ETL | Hardware | High Availability | Hints | Index | Misc | Operating Systems | Performance Tuning | Replication | T-SQL | Views


              © 1999-2008 by T10 Media. All rights reserved