Sdílet prostřednictvím


Dotaz FOR XML ve srovnání s vnořeným dotazem FOR XML

platí pro:SQL ServerAzure SQL DatabaseAzure SQL Managed InstanceSQL databáze v Microsoft Fabric

Tento článek porovnává dotaz na jednu úroveň FOR XML s vnořeným FOR XML dotazem. Jednou z výhod použití vnořených FOR XML dotazů je, že pro výsledky dotazu můžete zadat kombinaci xml orientovaných na atributy a elementy. Příklad ukazuje tuto výhodu.

Ukázky kódu v tomto článku používají ukázkovou databázi AdventureWorks2025 nebo AdventureWorksDW2025, kterou si můžete stáhnout z domovské stránky Microsoft SQL Serveru pro ukázky a komunitní projekty .

Examples

Následující SELECT dotaz načte informace o kategorii produktů a podkategorie v AdventureWorks2025 databázi. V dotazu nejsou žádné vnořené FOR XML.

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

Tady je částečný výsledek:

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

Pokud zadáte direktivu ELEMENTS v dotazu, obdržíte výsledek orientovaný na element, jak je znázorněno v následujícím fragmentu výsledku:

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

Dále předpokládejme, že chcete vygenerovat hierarchii XML, která je kombinací atributově orientovaného a elementově orientovaného XML, jak je znázorněno v následujícím fragmentu:

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

V předchozím fragmentu jsou informace o kategoriích produktů, jako je ID kategorie a název kategorie, atributy. Informace v podkategorii jsou však zaměřené na elementy. Pokud chcete vytvořit <ProductCategory> prvek, můžete napsat FOR XML dotaz, jak je znázorněno v následujícím příkladu:

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

Tady je výsledek:

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

Pokud chcete vytvořit vnořené <ProductSubCategory> elementy ve formátu XML, který chcete použít, přidejte vnořený FOR XML dotaz, jak je znázorněno v následující ukázce kódu:

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;

Všimněte si následující položky v předchozím dotazu:

  • Vnitřní FOR XML dotaz načte informace o podkategorii produktu. Direktiva ELEMENTS je přidána do vnitřní FOR XML ke generování elementově zaměřeného XML, které je přidáno do XML vygenerovaného vnějším dotazem. Vnější dotaz ve výchozím nastavení generuje XML orientovaný na atributy.

  • Ve vnitřním dotazu je direktiva zadána, TYPE takže výsledek je typu XML . Pokud TYPE není zadán, výsledek se vrátí jako typ nvarchar(max) a data XML se vrátí jako entity.

  • Vnější dotaz také určuje direktivu TYPE . Výsledek tohoto dotazu se proto klientovi vrátí jako typ XML .

Tady je částečný výsledek:

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

Následující dotaz je pouze rozšířením předchozího dotazu. Zobrazuje úplnou hierarchii produktů v AdventureWorks2025 databázi. Sem patří:

  • Kategorie produktu
  • Podkategorie produktů v každé kategorii
  • Modely produktů v jednotlivých podkategoriích
  • Produkty v jednotlivých modelech

Při pochopení AdventureWorks2025 databáze může být užitečný následující dotaz:

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;

Tady je částečný výsledek:

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

Pokud odeberete direktivu ELEMENTS z vnořeného FOR XML dotazu, který generuje podkategorie produktu, celý výsledek je orientovaný na atribut. Tento dotaz pak můžete napsat bez vnoření. Přidání ELEMENTS má za následek, že XML je částečně orientované na atributy a částečně na elementy. Tento výsledek nejde vygenerovat jedním dotazem na úrovni FOR XML .