I have a table like this (simplified):
ID | Name | Parent
---------------------------------
1 | IND | NULL
2 | INS | 5
3 | CON
You can also do this without creating a separate function, by including the sub-query as an additional column that returns XML. For example, the following will return a hierarchical XML document containing users and their associated list of roles:
SELECT
FirstName, LastName,
CONVERT(XML,
(SELECT r.UserID, r.RoleID
FROM global.[UserRole] r
WHERE r.USerID = [user].UserID
FOR XML RAW ('Role'), ELEMENTS, root('Roles')
))
FROM global.[user]
FOR XML RAW ('User'), ELEMENTS, root('Users')
Based on Recep's answer (see comments) I created the following solution for this problem:
1. Create a recursive function
CREATE function SelectChild(@key as int)
returns xml
begin
return (
select
IdIndustry as "@key",
ParentId as "@parentkey",
IndustryCode as "@Code",
IndustryName as "@Name",
dbo.SelectChild(IdIndustry)
from tblIndustryCodes
where ParentId = @key
for xml path('record'), type
)
end
2. Build a SELECT statement, that calls the function
SELECT
IdIndustry AS "@key",
'' AS "@parentkey",
IndustryCode as "@Code",
IndustryName as "@Name",
dbo.SelectChild(IdIndustry)
FROM dbo.tblIndustryCodes
WHERE ParentId is null
FOR XML PATH ('record')
This creates a hierarchical XML, no matter how deep the tree actually is:
<record key="1" parentkey="" Code="IND" Name="Industry">
<record key="2" parentkey="1" Code="AUTO" Name="Automotive" />
<record key="3" parentkey="1" Code="PHARM" Name="Pharmaceuticals" />
</record>
<record key="4" parentkey="" Code="FIN" Name="Finance">
<record key="5" parentkey="4" Code="CFIN" Name="Corporate Finance">
<record key="6" parentkey="5" Code="CMRKT" Name="Capital Markets" />
</record>
</record>
<record key="7" parentkey="" Code="CON" Name="Cosulting">
<record key="8" parentkey="7" Code="IMPL" Name="Implementation" />
<record key="9" parentkey="7" Code="STRAT" Name="Strategy" />
</record>