Partager via


Comparaison de la requête FOR XML et de la requête FOR XML imbriquée

Cette rubrique compare une requête FOR XML de niveau unique à une requête FOR XML imbriquée. L’un des avantages de l’utilisation de requêtes FOR XML imbriquées est que vous pouvez spécifier une combinaison de xml centrés sur les attributs et centrés sur les éléments pour les résultats de requête. L’exemple illustre cela.

Exemple :

La requête suivante SELECT récupère les informations de catégorie de produit et de sous-catégorie dans la base de données AdventureWorks2012 . Il n’existe aucun FOR XML imbriqué dans la requête.

USE AdventureWorks2012;  
GO  
SELECT   ProductCategory.ProductCategoryID,   
         ProductCategory.Name as CategoryName,  
         ProductSubCategory.ProductSubCategoryID,   
         ProductSubCategory.Name  
FROM     Production.ProductCategory, Production.ProductSubCategory  
WHERE    ProductCategory.ProductCategoryID = ProductSubCategory.ProductCategoryID  
ORDER BY ProductCategoryID  
FOR XML AUTO, TYPE  
GO  

Voici le résultat partiel :

<ProductCategory ProductCategoryID="1" CategoryName="Bike">  
  <ProductSubCategory ProductSubCategoryID="1" Name="Mountain Bike"/>  
  <ProductSubCategory ProductSubCategoryID="2" Name="Road Bike"/>  
  <ProductSubCategory ProductSubCategoryID="3" Name="Touring Bike"/>  
</ProductCategory>  
...  

Si vous spécifiez la ELEMENTS directive dans la requête, vous recevez un résultat centré sur les éléments, comme indiqué dans le fragment de résultat suivant :

<ProductCategory>  
  <ProductCategoryID>1</ProductCategoryID>  
  <CategoryName>Bike</CategoryName>  
  <ProductSubCategory>  
    <ProductSubCategoryID>1</ProductSubCategoryID>  
    <Name>Mountain Bike</Name>  
  </ProductSubCategory>  
  <ProductSubCategory>  
     ...  
  </ProductSubCategory>  
</ProductCategory>  

Ensuite, supposons que vous souhaitez générer une hiérarchie XML qui est une combinaison de xml centrés sur les attributs et centrés sur les éléments, comme indiqué dans le fragment suivant :

<ProductCategory ProductCategoryID="1" CategoryName="Bike">  
  <ProductSubCategory>  
    <ProductSubCategoryID>1</ProductSubCategoryID>  
    <SubCategoryName>Mountain Bike</SubCategoryName></ProductSubCategory>  
  <ProductSubCategory>  
     ...  
  <ProductSubCategory>  
     ...  
</ProductCategory>  

Dans le fragment précédent, les informations de catégorie de produit telles que l’ID de catégorie et le nom de catégorie sont des attributs. Toutefois, les informations de sous-catégorie sont centrées sur les éléments. Pour construire l’élément <ProductCategory>, vous pouvez écrire une requête FOR XML comme indiqué ci-dessous :

SELECT ProductCategoryID, Name as CategoryName  
FROM Production.ProductCategory ProdCat  
ORDER BY ProductCategoryID  
FOR XML AUTO, TYPE  

Voici le résultat obtenu :

< ProdCat ProductCategoryID="1" CategoryName="Bikes" />  
< ProdCat ProductCategoryID="2" CategoryName="Components" />  
< ProdCat ProductCategoryID="3" CategoryName="Clothing" />  
< ProdCat ProductCategoryID="4" CategoryName="Accessories" />  

Pour construire les éléments imbriqués <ProductSubCategory> dans le code XML souhaité, vous ajoutez ensuite une requête imbriquée FOR XML , comme indiqué dans les éléments suivants :

SELECT ProductCategoryID, Name as CategoryName,  
       (SELECT ProductSubCategoryID, Name SubCategoryName  
        FROM   Production.ProductSubCategory  
        WHERE ProductSubCategory.ProductCategoryID =   
              ProductCategory.ProductCategoryID  
        FOR XML AUTO, TYPE, ELEMENTS  
       )  
FROM Production.ProductCategory  
ORDER BY ProductCategoryID  
FOR XML AUTO, TYPE  

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

  • La requête interne FOR XML récupère les informations de sous-catégorie de produit. La ELEMENTS directive est ajoutée dans l’intérieur FOR XML pour générer du code XML centré sur l’élément qui est ajouté au code XML généré par la requête externe. Par défaut, la requête externe génère du code XML centré sur les attributs.

  • Dans la requête interne, la TYPE directive est spécifiée de sorte que le résultat soit de type xml . Si TYPE n'est pas spécifié, le résultat est retourné en tant que type nvarchar(max) et les données XML sont retournées en tant qu’entités.

  • La requête externe spécifie également la TYPE directive. Par conséquent, le résultat de cette requête est retourné au client en tant que type xml .

Voici le résultat partiel :

<ProductCategory ProductCategoryID="1" CategoryName="Bike">  
  <ProductSubCategory>  
    <ProductSubCategoryID>1</ProductSubCategoryID>  
    <SubCategoryName>Mountain Bike</SubCategoryName></ProductSubCategory>  
  <ProductSubCategory>  
     ...  
  <ProductSubCategory>  
     ...  
</ProductCategory>  

La requête suivante n’est qu’une extension de la requête précédente. Il affiche la hiérarchie complète des produits dans la base de données AdventureWorks2012 . Notamment :

  • Catégories de produits

  • Sous-catégories de produits dans chaque catégorie

  • Modèles de produit dans chaque sous-catégorie

  • Produits dans chaque modèle

Vous trouverez peut-être la requête suivante utile pour comprendre la base de données AdventureWorks2012 :

SELECT ProductCategoryID, Name as CategoryName,  
       (SELECT ProductSubCategoryID, Name SubCategoryName,  
               (SELECT ProductModel.ProductModelID,   
                       ProductModel.Name as ModelName,  
                       (SELECT ProductID, Name as ProductName, Color  
                        FROM   Production.Product  
                        WHERE  Product.ProductModelID =   
                               ProductModel.ProductModelID  
                        FOR XML AUTO, TYPE)  
                FROM   (SELECT distinct ProductModel.ProductModelID,   
                               ProductModel.Name  
                        FROM   Production.ProductModel,   
                               Production.Product  
                        WHERE  ProductModel.ProductModelID =   
                               Product.ProductModelID  
                        AND    Product.ProductSubCategoryID =   
                               ProductSubCategory.ProductSubCategoryID)   
                                  ProductModel  
                FOR XML AUTO, type  
               )  
        FROM Production.ProductSubCategory  
        WHERE ProductSubCategory.ProductCategoryID =   
              ProductCategory.ProductCategoryID  
        FOR XML AUTO, TYPE, ELEMENTS  
       )  
FROM Production.ProductCategory  
ORDER BY ProductCategoryID  
FOR XML AUTO, TYPE  

Voici le résultat partiel :

<Production.ProductCategory ProductCategoryID="1" CategoryName="Bikes">  
  <Production.ProductSubCategory>  
    <ProductSubCategoryID>1</ProductSubCategoryID>  
    <SubCategoryName>Mountain Bikes</SubCategoryName>  
    <ProductModel ProductModelID="19" ModelName="Mountain-100">  
      <Production.Product ProductID="771"   
                ProductName="Mountain-100 Silver, 38" Color="Silver" />  
      <Production.Product ProductID="772"   
                ProductName="Mountain-100 Silver, 42" Color="Silver" />  
      <Production.Product ProductID="773"   
                ProductName="Mountain-100 Silver, 44" Color="Silver" />  
        ...  
    </ProductModel>  
     ...  

Si vous supprimez la ELEMENTS directive de la requête imbriquée FOR XML qui génère des sous-catégories de produit, le résultat entier est centré sur les attributs. Vous pouvez ensuite écrire cette requête sans imbrication. L’ajout de ELEMENTS résultats dans un code XML centré sur les attributs et partiellement centré sur les éléments. Ce résultat ne peut pas être généré par une requête FOR XML de niveau unique.

Voir aussi

Utiliser des requêtes FOR XML imbriquées