Delen via


FOR XML-query vergeleken met geneste FOR XML-query

van toepassing op:SQL ServerAzure SQL DatabaseAzure SQL Managed InstanceSQL-database in Microsoft Fabric

In dit artikel wordt een query met één niveau FOR XML vergeleken met een geneste query FOR XML. Een van de voordelen van het gebruik van geneste FOR XML query's is dat u een combinatie van kenmerkgerichte en elementgerichte XML voor queryresultaten kunt opgeven. In het voorbeeld ziet u dit voordeel.

De codevoorbeelden in dit artikel gebruiken de AdventureWorks2025 of AdventureWorksDW2025 voorbeelddatabase die u kunt downloaden van de startpagina van Microsoft SQL Server Samples en Community Projects .

Voorbeelden

Met de volgende SELECT query worden productcategorie- en subcategoriegegevens opgehaald in de AdventureWorks2025 database. Er is geen geneste FOR XML in de query.

USE AdventureWorks2022;
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

Dit is het gedeeltelijke resultaat:

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

Als u de ELEMENTS instructie in de query opgeeft, ontvangt u een elementgericht resultaat, zoals wordt weergegeven in het volgende resultaatfragment:

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

Stel vervolgens dat u een XML-hiërarchie wilt genereren die een combinatie is van kenmerkgericht en elementgericht XML, zoals wordt weergegeven in het volgende fragment:

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

In het vorige fragment zijn productcategoriegegevens, zoals categorie-id en categorienaam, kenmerken. De informatie over de subcategorie is echter elementgericht. Als u het <ProductCategory> element wilt maken, kunt u een FOR XML query schrijven zoals wordt weergegeven in het volgende:

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

Dit is het resultaat:

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

Als u de geneste <ProductSubCategory> elementen in de gewenste XML wilt maken, voegt u vervolgens een geneste FOR XML query toe, zoals wordt weergegeven in het volgende codevoorbeeld:

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

Let op het volgende in de vorige query:

  • De binnenste FOR XML query haalt productsubcategoriegegevens op. De ELEMENTS-instructie wordt aan de innerlijke FOR XML toegevoegd om element-centrische XML te genereren, die vervolgens wordt toegevoegd aan de XML die door de buitenste query wordt gegenereerd. De buitenste query genereert standaard attribuutgerichte XML.

  • In de binnenste query wordt de TYPE instructie opgegeven, zodat het resultaat van het XML-type is. Als TYPE niet is opgegeven, wordt het resultaat geretourneerd als nvarchar(max) type en worden de XML-gegevens geretourneerd als XML-entiteiten.

  • De buitenste query specificeert ook de TYPE directief. Daarom wordt het resultaat van deze query als XML-type naar de client geretourneerd.

Dit is het gedeeltelijke resultaat:

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

De volgende query is slechts een uitbreiding van de vorige query. De volledige producthiërarchie in de AdventureWorks2025 database wordt weergegeven. Dit omvat:

  • Productcategorieën
  • Productsubcategorieën van elke categorie
  • Productmodellen in elke subcategorie
  • Producten in elk model

Mogelijk vindt u de volgende query nuttig bij het begrijpen van de AdventureWorks2025 database:

SELECT ProductCategoryID,
    Name AS CategoryName,
    (
        SELECT ProductSubCategoryID,
            Name AS 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;

Dit is het gedeeltelijke resultaat:

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

Als u de ELEMENTS directive verwijdert uit de FOR XML geneste query die productsubcategorieën genereert, is het hele resultaat attribuutgericht. U kunt deze query vervolgens schrijven zonder te nesten. De toevoeging van ELEMENTS resultaten in een XML die deels kenmerkgericht en deels elementgericht is. Dit resultaat kan niet worden gegenereerd door een query op één niveau FOR XML .