2010-11-23 25 views
10

J'ai une table avec les colonnes NodeId, NodeName, ParentNodeId et je souhaite extraire des données de table entières sous la forme de Xml comme suit en utilisant la requête SQL. Je pense que le mode XML PATH dans le serveur Sql peut être utilisé pour cela (j'utilise SQL Server 2008) en utilisant la récursivité, mais je ne sais pas comment. Merci à l'avanceRequête pour obtenir une sortie XML pour les données hiérarchiques à l'aide de FOR XML PATH dans SQL Server

<?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> 
+0

Avez-vous pu ajouter en-tête? –

Répondre

7

Je l'ai résolu en utilisant une procédure stockée et une fonction récursive. code illustré 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 
3

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 en profondeur .... plus

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

<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 un moyen de le faire avec un CTE récursive (expression commune tableau), mais cela ne fonctionne pas :-(

+0

merci pour votre réponse. – RKP