FOR XML-fråga jämfört med kapslad FOR XML-fråga

Gäller för:SQL ServerAzure SQL DatabaseAzure SQL Managed InstanceSQL-databas i Microsoft Fabric

I den här artikeln jämförs en fråga på en nivå FOR XML med en kapslad FOR XML fråga. En av fördelarna med att använda kapslade FOR XML frågor är att du kan ange en kombination av attributcentrerad och elementcentrerad XML för frågeresultat. Exemplet visar den här fördelen.

Kodexemplen i den här artikeln använder AdventureWorks2025- eller AdventureWorksDW2025-exempeldatabasen, som du kan ladda ned från startsidan Microsoft SQL Server Samples och Community Projects.

Examples

Följande SELECT fråga hämtar produktkategori och underkategoriinformation i AdventureWorks2025 databasen. Det finns ingen kapslad FOR XML i sökfrågan.

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

Här är det partiella resultatet:

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

Om du anger ELEMENTS direktivet i frågan får du ett elementcentrerat resultat, enligt följande resultatfragment:

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

Anta sedan att du vill generera en XML-hierarki som är en kombination av attributcentrerad och elementcentrerad XML, enligt följande fragment:

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

I föregående fragment är produktkategoriinformation som kategori-ID och kategorinamn attribut. Underkategoriinformationen är dock elementcentrerad. Om du vill konstruera elementet <ProductCategory> kan du skriva en FOR XML fråga enligt följande:

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

Här är resultatet:

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

Om du vill konstruera de kapslade <ProductSubCategory> elementen i den XML du vill använda lägger du sedan till en kapslad FOR XML fråga, som du ser i följande kodexempel:

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;

Observera följande i föregående fråga:

  • Den inre FOR XML frågan hämtar produktunderkategoriinformation. Direktivet ELEMENTS läggs till i det inre FOR XML för att generera elementscentrerad XML som läggs till i XML som genereras av den yttre frågan. Som standard genererar den yttre frågan attributcentrerad XML.

  • I den inre frågan TYPE anges direktivet så att resultatet är av xml-typ . Om TYPE inte anges returneras resultatet som nvarchar(max) typ och XML-data returneras som entiteter.

  • Den yttre frågan anger också TYPE direktivet. Därför returneras resultatet av den här frågan till klienten som xml-typ .

Här är det partiella resultatet:

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

Följande fråga är bara ett tillägg till den föregående frågan. Den visar den fullständiga produkthierarkin i AdventureWorks2025 databasen. Detta omfattar:

  • Produktkategorier
  • Produktunderkategorier i varje kategori
  • Produktmodeller i varje underkategori
  • Produkter i varje modell

Du kanske tycker att följande fråga är användbar för att förstå AdventureWorks2025 databasen:

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;

Här är det partiella resultatet:

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

Om du tar bort ELEMENTS direktivet från den kapslade FOR XML frågan som genererar produktunderkategorier är hela resultatet attributcentrerat. Du kan sedan skriva den här frågan utan kapsling. Tillägget av ELEMENTS resulterar i en XML som delvis är attributcentrerad och delvis elementcentrerad. Det här resultatet kan inte genereras av en en-nivå-fråga FOR XML.