Możesz użyć rekurencyjnego CTE, aby zbudować hierarchię i przejść przez poziomy, aby zbudować XML.
-- Sample data
create table MyDatabaseTable(ID int, Name varchar(10), Parent int, [Order] int)
insert into MyDatabaseTable values
(1, 'N1', null, 1),
(2, 'N1_1', 1 , 1),
(3, 'N1_1_1', 2 , 1),
(4, 'N1_1_2', 2 , 2),
(5, 'N1_2', 1 , 2),
(6, 'N2', null, 1),
(7, 'N2_1', 6 , 1)
-- set @Root to whatever node should be root
declare @Root int = 1
-- Worktable that holds temp xml data and level
declare @Tree table(ID int, Parent int, [Order] int, [Level] int, XMLCol xml)
-- Recursive cte that builds @tree
;with Tree as
(
select
M.ID,
M.Parent,
M.[Order],
1 as [Level]
from MyDatabaseTable as M
where M.ID = @Root
union all
select
M.ID,
M.Parent,
M.[Order],
Tree.[Level]+1 as [Level]
from MyDatabaseTable as M
inner join Tree
on Tree.ID = M.Parent
)
insert into @Tree(ID, Parent, [Order], [Level])
select *
from Tree
declare @Level int
select @Level = max([Level]) from @Tree
-- Loop for each level
while @Level > 0
begin
update Tree set
XMLCol = (select
M.ID as '@ID',
M.Name as '@Name',
M.Parent as '@Parent',
M.[Order] as '@Order',
(select XMLCol as '*'
from @Tree as Tree2
where Tree2.Parent = M.ID
order by Tree2.[Order]
for xml path(''), type)
from MyDatabaseTable as M
where M.ID = Tree.ID
order by M.[Order]
for xml path('item'))
from @Tree as Tree
where Tree.[Level] = @Level
set @Level = @Level - 1
end
select XMLCol
from @Tree
where ID = @Root
Wynik
<item ID="1" Name="N1" Order="1">
<item ID="2" Name="N1_1" Parent="1" Order="1">
<item ID="3" Name="N1_1_1" Parent="2" Order="1" />
<item ID="4" Name="N1_1_2" Parent="2" Order="2" />
</item>
<item ID="5" Name="N1_2" Parent="1" Order="2" />
</item>