Check an iterative method:
drop table if exists #Table
create table #Table
(
ID int not null IDENTITY(1, 1) PRIMARY KEY,
ParentID int null FOREIGN KEY REFERENCES #Table(ID),
NodeText varchar(50) not null,
RecOrder int not null
)
declare @xml as xml = '<?xml version="1.0" encoding="us-ascii" ?>
<TreeView>
<node text="Asia">
<node text="China">
<node text="Beijing"/>
</node>
<node text="Pakistan"/>
<node text="India"/>
<node text="Sri Lanka"/>
</node>
<node text="Europe">
<node text="Germany"/>
</node>
<node text="America"/>
<node text="Africa"/>
</TreeView>'
---
declare @c int = @xml.value('count(//node)', 'int')
declare @i int = 0
while @i < @c
begin
set @i += 1
insert into #Table(NodeText, RecOrder)
select t.n.value('@text', 'varchar(50)'), 1
from @xml.nodes('(//node)[sql:variable("@i")]') t(n)
declare @id int = SCOPE_IDENTITY()
set @xml.modify( 'insert attribute ID {sql:variable("@id")} into (//node)[sql:variable("@i")][1]')
end
;
with Q as
(
select
t.n.value('@ID', 'int') as id,
p.n.value('@ID', 'int') as parent_id
from @xml.nodes('//node') t(n)
cross apply t.n.nodes('..') p(n)
)
update t
set ParentID = Q.parent_id
from #Table as t
left join Q on Q.id = t.id
;
with Q as
(
select ID, ROW_NUMBER() over (partition by ParentID order by ID) as rn
from #Table
)
update t
set RecOrder = Q.rn
from #Table as t
inner join Q on Q.id = t.id
select * from #Table order by ID
The guessed output is:
ID ParentID NodeText RecOrder
1 NULL Asia 1
2 1 China 1
3 2 Beijing 1
4 1 Pakistan 2
5 1 India 3
6 1 Sri Lanka 4
7 NULL Europe 2
8 7 Germany 1
9 NULL America 3
10 NULL Africa 4