Compartilhar via


Consulta FOR XML comparada com consulta FOR XML aninhada

Este tópico compara uma consulta FOR XML de nível único a uma consulta FOR XML aninhada. Um dos benefícios do uso de consultas FOR XML aninhadas é que você pode especificar uma combinação de XML centrado em atributo e centrado em elemento para resultados de consulta. O exemplo demonstra isso.

Exemplo

A consulta a seguir SELECT recupera informações de categoria de produto e subcategoria no banco de dados AdventureWorks2012 . Não há nenhum FOR XML aninhado na consulta.

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  

Este é 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 você especificar a ELEMENTS diretiva na consulta, receberá um resultado centrado em elemento, conforme 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>  

Em seguida, suponha que você queira gerar uma hierarquia XML que seja uma combinação de XML centrado em atributo e centrado em elemento, conforme mostrado no seguinte fragmento:

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

No fragmento anterior, as informações de categoria do produto, como ID da categoria e nome da categoria, são atributos. No entanto, as informações de subcategoria são centradas em elementos. Para construir o <ProductCategory> elemento, você 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  

Este é 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 desejado, adicione uma consulta aninhada FOR XML, conforme mostrado no seguinte:

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  

Observe o seguinte na consulta anterior:

  • A consulta interna FOR XML recupera informações de subcategoria do produto. A ELEMENTS diretiva é adicionada na parte interna FOR XML para gerar XML centrado em elemento que é adicionado ao XML gerado pela consulta externa. Por padrão, a consulta externa gera XML centrado em atributo.

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

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

Este é o resultado parcial:

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

A consulta a seguir é apenas uma extensão da consulta anterior. Ele mostra a hierarquia completa do produto no banco de dados AdventureWorks2012 . Isso inclui o seguinte:

  • Categorias de produto

  • Subcategorias de produto em cada categoria

  • Modelos de produto em cada subcategoria

  • Produtos em cada modelo

Você pode achar a seguinte consulta útil para entender o banco de dados 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  

Este é 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 você remover a ELEMENTS diretiva da consulta aninhada FOR XML que gera subcategorias do produto, todo o resultado será centralizado em atributos. Em seguida, você pode escrever essa consulta sem aninhar. A adição de ELEMENTS resulta em um XML que é parcialmente centrado em atributos e parcialmente centrado em elemento. Esse resultado não pode ser gerado por uma consulta FOR XML de nível único.

Consulte Também

Usar consultas FOR XML aninhadas