Another solution to the problem is to determine the Level of the row on the fly. The user-defined function below accomplishes this task.
CREATE FUNCTION [dbo].[ufn_GetTreeNodeLevel] ( @pCurrentNode INT )
RETURNS INT
AS
BEGIN
DECLARE @vParentID INT
IF @pCurrentNode = 0 OR @pCurrentNode IS NULL
RETURN 0
SELECT @vParentID = [ParentID]
FROM [dbo].[Hierarchy]
WHERE [ID] = @pCurrentNode
RETURN [dbo].[ufn_GetTreeNodeLevel] ( @vParentID ) + 1
END
GO
The logic behind this user-defined function is in the following code:
RETURN [dbo].[ufn_GetTreeNodeLevel] ( @vParentID ) + 1
As can be seen, the function calls itself. This type of function is a
recursive function. A recursive function is simply a function that calls
itself. In this user-defined function, to get the level of the current
node, it simply adds 1 to the level of its parent. The function stops
calling itself when the input node (@pCurrentNode) is already 0 or null and
simply return 0.
This user-defined function can only process until 31 levels within the
tree. This limitation is not a limitation of the function itself but a
limitation of SQL Server because in SQL Server, the maximum number of nesting
levels is 32. Nesting occurs when one function/ stored procedure calls
another function/stored procedure, which is the case with this recursive
function.
To validate the output of this function, simply run the following SELECT
statement:
SELECT *, [dbo].[ufn_GetTreeNodeLevel] ( [ID] ) AS [Level]
FROM [dbo].[Hierarchy]
GO
ID ParentID Name Level Level
----------- ----------- --------------------------------------------- ------- --------
1 NULL Asia 1 1
2 NULL Africa 1 1
3 NULL Antarctica 1 1
4 NULL Australia 1 1
5 NULL Europe 1 1
6 NULL North America 1 1
7 NULL South America 1 1
8 6 Canada 2 2
9 6 United States of America 2 2
10 9 Alaska 3 3
11 9 Alabama 3 3
12 9 Arkansas 3 3
13 9 Arizona 3 3
14 9 California 3 3
15 9 Colorado 3 3
16 9 Connecticut 3 3
17 9 District of Columbia 3 3
18 9 Delaware 3 3
19 9 Florida 3 3
20 9 Georgia 3 3
21 14 Los Angeles 4 4
22 19 Miami 4 4
23 20 Atlanta 4 4
We can now get rid of the [Level] column and use this function to derive the
level of each row. This addresses the issue of newly inserted rows as
well as newly created level within the hierarchy.