Хорошо, значит, вы просили другие способы.Это немного странно.
CREATE TABLE employee (empid int, empname varchar(20), managerID int)
GO
insert into employee
select 1,'A',null union all
select 2,'B',1 union all
select 3,'C',1 union all
select 4,'D',2
GO
CREATE FUNCTION [dbo].[GetEmployeeTree](@ManagerId int)
RETURNS XML
WITH RETURNS NULL ON NULL INPUT
BEGIN RETURN
(SELECT empID as '@Id',
empname AS '@Name',
dbo.GetEmployeeTree(empid)
FROM employee em
WHERE ManagerId=@ManagerId
FOR XML PATH('Employee'), TYPE)
END
GO
SELECT empID as '@Id',
empname AS '@Name',
dbo.GetEmployeeTree(empId)
FROM employee
WHERE managerId is null
FOR XML PATH('Employee'), ROOT('Employees')
Что дает этот вывод
<Employees>
<Employee Id="1" Name="A">
<Employee Id="2" Name="B">
<Employee Id="4" Name="D" />
</Employee>
<Employee Id="3" Name="C" />
</Employee>
</Employees>
Я фактически использовал это для генерации больших деревьев XML с десятками тысяч узлов, и это довольно быстро.Вероятно, есть способ объединить корневой запрос с дочерним, но я пока не совсем понял.Когда я использовал эту технику в прошлом, я использовал отдельную ссылку и таблицу узлов для определения иерархии, и она работает немного чище, когда вы делаете это.