Requête pour obtenir une sortie XML pour les données hiérarchiques en utilisant FOR XML PATH dans SQL Server

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

Question

J'ai une table avec des colonnes NodeId, NODename, ParentNodeId et je veux ouput données de tableau entier sous la forme d'Xml comme l'utilisation de requête SQL suivante. Je pense que pour le mode PATH XML dans le serveur Sql peut être utilisé pour atteindre cet objectif (j'utilise SQL Server 2008) en utilisant récursion, mais pas sûr. Merci à l'avance

<?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>
Était-ce utile?

La solution

I résolu à l'aide d'une procédure stockée et une fonction récursive. le code ci-dessous. (En fait je voulais que cela générer un xml menu, de sorte que le code est affiché pour le menu.

    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

Autres conseils

Cette requête fera - cependant, ce n'est pas très propre dans ce que vous devez définir « manuellement » l'imbrication et il ne sera pas seulement l'échelle automatiquement à des niveaux plus profonds ....

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')

sortie est la suivante:

<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>

J'espérais qu'il y aurait une façon de le faire avec un CTE récursive (Common Table Expression), mais cela ne fonctionne pas: - (

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top