Consulta para obtener la salida XML de datos jerárquicos utilizando para la trayectoria XML en SQL Server

StackOverflow https://stackoverflow.com/questions/4256900

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>
¿Fue útil?

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ó: - (

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top