Consulta para obtener la salida XML de datos jerárquicos utilizando para la trayectoria XML en SQL Server
-
27-09-2019 - |
Pregunta
Tengo una tabla con columnas NODEID, NOMBRENODO, ParentNodeId y quiero ouput datos de toda la tabla en forma de XML como la siguiente consulta SQL usando. Creo que para el modo PATH XML en SQL Server pueden utilizar para lograr esto (yo uso de SQL Server 2008) utilizando la recursividad, pero no sabe cómo. Gracias de antemano
<?xml version="1.0" encoding="utf-8" ?>
<Nodes>
<Node Id="1" Name="node1">
<Node Id="11" Name="node11">
<Node Id="111" Name="node111" />
<Node Id="112" Name="node112" />
</Node>
</Node>
<Node Id="2" Name="node2">
<Node Id="21" Name="node21">
<Node Id="211" Name="node211" />
<Node Id="212" Name="node212" />
</Node>
</Node>
</Nodes>
Solución
I resolvió mediante un procedimiento almacenado y una función recursiva. código se muestra a continuación. (En realidad quería esto para generar un xml menú, así se muestra el código para el menú.
CREATE PROCEDURE [dbo].[usp_GetMenu]
AS
BEGIN
SET NOCOUNT ON;
SELECT dbo.fnGetMenuItems(MenuId)
FROM dbo.Menu
WHERE ParentMenuId IS NULL
FOR XML PATH('MenuItems')
END
GO
CREATE FUNCTION [dbo].[fnGetMenuItems]
(
@MenuId int
)
RETURNS XML
WITH RETURNS NULL ON NULL INPUT
AS
BEGIN
RETURN
(
SELECT MenuId AS "@Id"
, [Name] AS "@Name"
, [URL] AS "@URL"
, [Key] AS "@Key"
, [dbo].[fnGetMenuItems](MenuId)
FROM dbo.Menu
WHERE ParentMenuId = @MenuId
FOR XML PATH('MenuItem'),TYPE
)
END
GO
Otros consejos
Esta consulta hacerlo - sin embargo, no es muy limpio en el que usted tiene que "manualmente" definir la anidación y que no sólo va a escalar automáticamente a más niveles de profundidad ....
SELECT
n.ID AS '@Id',
n.NAME AS '@Name',
(SELECT
n2.ID AS '@Id',
n2.NAME AS '@Name',
(SELECT
n3.ID AS '@Id',
n3.NAME AS '@Name'
FROM
dbo.Nodes n3
WHERE
n3.ParentNode = n2.ID
FOR XML PATH('Node'), TYPE
)
FROM
dbo.Nodes n2
WHERE
n2.ParentNode = n.ID
FOR XML PATH('Node'), TYPE
)
FROM
dbo.Nodes n
WHERE
n.ParentNode IS NULL
FOR XML PATH('Node'), ROOT('Nodes')
La salida es:
<Nodes>
<Node Id="1" Name="node1">
<Node Id="11" Name="node11">
<Node Id="111" Name="node111" />
<Node Id="112" Name="node112" />
</Node>
</Node>
<Node Id="2" Name="node2">
<Node Id="21" Name="node21">
<Node Id="211" Name="node211" />
<Node Id="212" Name="node212" />
</Node>
</Node>
</Nodes>
Tenía la esperanza de que habría una manera de hacer esto con un CTE recursiva (expresión de tabla común), pero que no funcionó: - (