Partager via


Requêtes FOR XML imbriquées

Dans SQL Server 2000, vous pouvez spécifier la clause FOR XML uniquement au niveau supérieur d'une requête SELECT. Le document XML obtenu est essentiellement renvoyé au client en vue de subir un traitement supplémentaire. Toutefois, à compter de SQL Server 2005, le type de données xml et la directive TYPE dans les requêtes FOR XML permettent au XML retourné par les requêtes FOR XML d'être traité de manière supplémentaire sur le serveur.

Traitement avec des variables de type xml

Vous pouvez affecter le résultat de la requête FOR XML à une variable de type xml ou bien utiliser XQuery pour interroger le résultat et affecter celui-ci à une variable de type xml en vue d'un traitement supplémentaire.

USE AdventureWorks2008R2;
GO
DECLARE @x xml;
SET @x=(SELECT ProductModelID, Name
        FROM Production.ProductModel
        WHERE ProductModelID=122 OR ProductModelID=119
        FOR XML RAW, TYPE);
SELECT @x;

-- Résultat

--<row ProductModelID="122" Name="All-Purpose Bike Stand" />

--<row ProductModelID="119" Name="Bike Wash" />

Vous pouvez poursuivre le traitement du document XML renvoyé dans la variable @x à l'aide de l'une des méthodes de type de données xml. Par exemple, vous pouvez extraire la valeur de l'attribut ProductModelID à l'aide de la méthode value().

DECLARE @i int;
SET @i = (SELECT @x.value('/row[1]/@ProductModelID[1]', 'int'));
SELECT @i;

Dans l'exemple suivant, le résultat de la requête FOR XML renvoyé est de type xml car la directive TYPE est spécifiée dans la clause FOR XML.

SELECT ProductModelID, Name
FROM Production.ProductModel
WHERE ProductModelID=119 OR ProductModelID=122
FOR XML RAW, TYPE,ROOT('myRoot');

Voici le résultat obtenu :

<myRoot>

<row ProductModelID="122" Name="All-Purpose Bike Stand" />

<row ProductModelID="119" Name="Bike Wash" />

</myRoot>

Étant donné que le résultat est de type xml, vous pouvez spécifier l'une des méthodes de type de données xml directement par rapport à ce document XML, comme le montre la requête suivante. Dans la requête, la méthode query() (type de données xml) est utilisée pour extraire le premier élément enfant <row> de l'élément <myRoot>.

SELECT  (SELECT ProductModelID, Name
         FROM Production.ProductModel
         WHERE ProductModelID=119 OR ProductModelID=122
         FOR XML RAW, TYPE,ROOT('myRoot')).query('/myRoot[1]/row[1]');

Voici le résultat obtenu :

<row ProductModelID="122" Name="All-Purpose Bike Stand" />

Renvoi de résultats de requêtes FOR XML internes à des requêtes externes en tant qu'instances de type xml

Vous pouvez écrire des requêtes FOR XML imbriquées où le résultat de la requête interne est retourné en tant que type xml à la requête externe. Exemple :

SELECT Col1, 
       Col2, 
       ( SELECT Col3, Col4 
        FROM  T2
        WHERE T2.Col = T1.Col
        ...
        FOR XML AUTO, TYPE )
FROM T1
WHERE ...
FOR XML AUTO, TYPE;

Notez les points suivants par rapport à la requête ci-dessus :

  • Le XML généré par la requête FOR XML interne est ajouté au XML généré par la requête FOR XML externe.

  • La requête interne spécifie la directive TYPE. Par conséquent, les données XML retournées par la requête interne sont du type xml. Si la directive TYPE n'est pas spécifiée, le résultat de la requête FOR XML interne est retourné en tant que nvarchar(max) et les données XML sont converties en entités.

Contrôle de la forme des données XML résultantes

Les requêtes FOR XML imbriquées vous permettent de mieux contrôler la forme des données XML résultantes. Dans SQL Server 2000, les requêtes en mode RAW et AUTO génèrent par défaut des données XML centrées sur l'attribut. Exemple :

USE AdventureWorks2008R2;
GO
SELECT ProductModelID, Name
FROM Production.ProductModel
WHERE ProductModelID=122 OR ProductModelID=119
FOR XML RAW;

Voici le résultat centré sur l'attribut obtenu :

<row ProductModelID="122" Name="All-Purpose Bike Stand" />

<row ProductModelID="119" Name="Bike Wash" />

En guise d'alternative, vous pouvez récupérer toutes les données XML en tant que données centrées sur l'élément en spécifiant la directive ELEMENTS. Exemple :

SELECT ProductModelID, Name
FROM Production.ProductModel
WHERE ProductModelID=122 OR ProductModelID=119
FOR XML RAW, ELEMENTS ;

Voici le résultat centré sur l'élément obtenu :

<row>

<ProductModelID>122</ProductModelID>

<Name>All-Purpose Bike Stand</Name>

</row>

<row>

<ProductModelID>119</ProductModelID>

<Name>Bike Wash</Name>

</row>

Dans SQL Server 2000, par conséquent, vous devez choisir le XML centré sur l'attribut ou centré sur l'élément comme résultat d'une requête. À compter de SQL Server 2005, toutefois, vous pouvez utiliser des requêtes FOR XML imbriquées pour construire des données XML centrées partiellement sur l'attribut et partiellement sur l'élément.

Pour plus d'informations sur la spécification de données XML centrées sur l'attribut et sur l'élément avec des requêtes FOR XML imbriquées, consultez Comparaison de la requête FOR XML et de la requête FOR XML imbriquée et Façonnement de données XML avec des requêtes FOR XML imbriquées.

Dans SQL Server 2000, vous pouvez construire des frères uniquement en écrivant des requêtes en mode EXPLICIT. Toutefois, cette méthode peut s'avérer lourde. À compter de SQL Server 2005, vous pouvez générer des hiérarchies XML qui incluent des frères en spécifiant des requêtes FOR XML en mode AUTO imbriquées. Pour plus d'informations, consultez Génération de frères à l'aide d'une requête imbriquée en mode AUTO.

Quel que soit le mode utilisé, les requêtes FOR XML imbriquées procurent davantage de contrôle dans la description de la forme des données XML résultantes. Elles peuvent être utilisées à la place des requêtes en mode EXPLICIT.

Exemples

Les rubriques suivantes fournissent des exemples de requêtes FOR XML imbriquées.