Technical Article

Print Tree


Printing trees was alway a painfull procedure joining tables to itselves and figuring out the parent/child relationships.

This stored proc crawls throug a table and prints formated nodes and node ids.

The tree is in following format (nothing to do with a real b-tree):

CREATE TABLE [dbo].[tree](
[treeid] [int] NOT NULL,
[parenttreeid] [int] NULL,
[nodename] [varchar](64) NULL,
[rootid] [int] NULL)

The table name and id types are hardcoded, but easy to change if someone prefers integers.

The rootid is the top of the whole tree. The proc takes any node and prints a subtree below that node.



create procedure [dbo].[DBA_PrintTree] (@root int)
set nocount on;

with btree (treeid,parenttreeid,nodename,level)
select treeid,parenttreeid,nodename,0 as level from tree
where treeid=@root
union all
select b1.treeid,b1.parenttreeid,b1.nodename,level+1  from tree b1 join btree b2 on b2.treeid=b1.parenttreeid 

select treeid,parenttreeid,nodename,level into #t from btree order by level, parenttreeid

declare @stack table(d int identity(1,1) primary key,node int)
declare @t table(treeid int,parenttreeid int,nodename varchar(64),level int)
declare @parent int,@nodename varchar(64),@level int,
@bid int,@bparent int
set @parent=@root
insert @t select * from #t where treeid =@root
select @nodename=nodename from @t
print @nodename
delete #t where treeid =@root
insert @stack values(@root)

while exists(select top 1 node from @stack)
while exists (select treeid from #t where parenttreeid=@parent)
select top 1 @bid=treeid,@bparent=parenttreeid,@nodename=nodename,@level=level from #t 
where parenttreeid=@parent order by nodename
insert @t values(@bid,@bparent,@nodename,@level)
print space(@level*5)+@nodename
delete #t where treeid=@bid
insert @stack values(@bid)
set @parent=@bid
delete @stack where d in (select max(d) from @stack)
select top 1 @parent=node from @stack order by d desc

select * from @t
drop table #t


1 (1)




1 (1)