Condividi tramite


Query FOR XML confrontata con query FOR XML nidificata

In questo argomento viene confrontata una query FOR XML a livello singolo con una query FOR XML nidificata. Uno dei vantaggi dell'uso di query FOR XML annidate è che è possibile specificare una combinazione di XML incentrato sugli attributi e incentrato sugli elementi per i risultati delle query. Nell'esempio viene illustrato questo.

Esempio

La query seguente SELECT recupera le informazioni relative alla categoria di prodotti e alla sottocategoria nel database AdventureWorks2012 . Nella query non è presente alcun FOR XML annidato.

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  

Risultato parziale:

<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 si specifica la ELEMENTS direttiva nella query, si riceve un risultato incentrato sugli elementi, come illustrato nel frammento di risultato seguente:

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

Si supponga quindi di voler generare una gerarchia XML che sia una combinazione di XML incentrato sugli attributi e incentrato sugli elementi, come illustrato nel frammento seguente:

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

Nel frammento precedente, le informazioni sulla categoria del prodotto, ad esempio l'ID categoria e il nome della categoria, sono attributi. Tuttavia, le informazioni sulla sottocategoria sono incentrate sugli elementi. Per costruire l'elemento<>ProductCategory, è possibile scrivere una FOR XML query come illustrato di seguito:

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

Risultato:

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

Per costruire gli elementi annidati <ProductSubCategory> nel codice XML che desideri, aggiungi una query nidificata FOR XML come illustrato di seguito:

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  

Dalla query precedente si noti quanto segue:

  • La query interna FOR XML recupera le informazioni sulla sottocategoria del prodotto. La direttiva ELEMENTS viene aggiunta all'interno di FOR XML per generare XML centrato sugli elementi aggiunto all'XML generato dalla query esterna. Per impostazione predefinita, la query esterna genera codice XML incentrato sugli attributi.

  • Nella query interna la TYPE direttiva viene specificata in modo che il risultato sia di tipo xml . Se TYPE non viene specificato, il risultato viene restituito come nvarchar(max) tipo e i dati XML vengono restituiti come entità.

  • La query esterna specifica anche la TYPE direttiva . Di conseguenza, il risultato di questa query viene restituito al client come tipo xml .

Risultato parziale:

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

La query seguente è solo un'estensione della query precedente. Mostra la gerarchia completa del prodotto nel database AdventureWorks2012 . Sono inclusi gli elementi seguenti:

  • Categorie di prodotti

  • Sottocategorie di prodotti in ogni categoria

  • Modelli di prodotto in ogni sottocategoria

  • Prodotti in ogni modello

È possibile che la query seguente sia utile per comprendere il database 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  

Risultato parziale:

<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 si rimuove la direttiva ELEMENTS dalla query nidificata FOR XML che genera sottocategorie di prodotti, l'intero risultato sarà incentrato sugli attributi. È quindi possibile scrivere questa query senza annidare. L'aggiunta di ELEMENTS risultati in un codice XML parzialmente incentrato sugli attributi e in parte incentrato sugli elementi. Questo risultato non può essere generato da una query FOR XML a livello singolo.

Vedere anche

Utilizzo di query FOR XML nidificate