Partilhar via


Consulta FOR XML comparada com consulta FOR XML aninhada

Aplica-se a:SQL ServerAzure SQL DatabaseAzure SQL Managed InstanceBase de dados SQL no Microsoft Fabric

Este artigo compara uma consulta de nível único FOR XML com uma consulta aninhada FOR XML . Um dos benefícios de usar consultas aninhadas FOR XML é que pode especificar uma combinação de XML centrado em atributos e centrado em elementos para os resultados das consultas. O exemplo demonstra este benefício.

Os exemplos de código neste artigo usam o banco de dados de exemplo AdventureWorks2025 ou AdventureWorksDW2025, que pode ser descarregado da página inicial de Exemplos e Projetos da Comunidade do Microsoft SQL Server.

Examples

A consulta seguinte SELECT recupera informações sobre categorias e subcategorias de produto na AdventureWorks2025 base de dados. Não há nenhum elemento FOR XML aninhado na consulta.

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

Eis o resultado parcial:

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

Se especificar a ELEMENTS diretiva na consulta, recebe um resultado centrado no elemento, como mostrado no seguinte fragmento de resultado:

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

De seguida, assuma que pretende gerar uma hierarquia XML que seja uma combinação de XML centrado nos atributos e nos elementos, como mostrado no seguinte fragmento:

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

No fragmento anterior, a informação da categoria do produto, como o ID da categoria e o nome da categoria, são atributos. No entanto, a informação da subcategoria é centrada no elemento. Para construir o <ProductCategory> elemento, pode escrever uma FOR XML consulta conforme mostrado no seguinte:

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

Eis o resultado:

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

Para construir os elementos aninhados <ProductSubCategory> no XML que pretende, adiciona-se depois uma consulta aninhada FOR XML , como mostrado no seguinte exemplo de código:

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;

Observe o seguinte na consulta anterior:

  • A consulta interna FOR XML recupera informação da subcategoria do produto. A ELEMENTS diretiva é adicionada no interior FOR XML para gerar um XML centrado no elemento que é adicionado ao XML gerado pela consulta externa. Por defeito, a consulta externa gera XML centrado nos atributos.

  • Na consulta interna, a TYPE diretiva é especificada para que o resultado seja do tipo xml . Se TYPE não for especificado, o resultado é devolvido como tipo nvarchar(max ) e os dados XML são devolvidos como entidades.

  • A consulta externa também especifica a TYPE diretiva. Portanto, o resultado desta consulta é devolvido ao cliente como tipo xml .

Eis o resultado parcial:

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

A consulta seguinte é apenas uma extensão da consulta anterior. Mostra a hierarquia completa do produto na AdventureWorks2025 base de dados. Isto inclui:

  • Categorias de produtos
  • Subcategorias de produtos em cada categoria
  • Modelos de produto em cada subcategoria
  • Produtos em cada modelo

Pode achar útil a seguinte consulta para compreender a AdventureWorks2025 base de dados:

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;

Eis o resultado parcial:

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

Se remover a ELEMENTS diretiva da consulta aninhada FOR XML que gera subcategorias de produto, o resultado completo é centrado no atributo. Pode então escrever esta consulta sem aninhamento. A adição de ELEMENTS resulta num XML que é parcialmente centrado no atributo e parcialmente no elemento. Este resultado não pode ser gerado por uma consulta de nível único FOR XML .