Query FOR XML e query nidificata FOR XML a confrontoFOR XML Query Compared to Nested FOR XML Query

In questo argomento viene messa a confronto una query FOR XML con un solo livello con una query FOR XML nidificata.This topic compares a single-level FOR XML query to a nested FOR XML query. Uno dei vantaggi dell'utilizzo di query FOR XML consiste nella possibilità di specificare una combinazione di XML incentrati sia sugli attributi che sugli elementi per i risultati della query.One of the benefits of using nested FOR XML queries is that you can specify a combination of attribute-centric and element-centric XML for query results. Tutto ciò è dimostrato nell'esempio riportato di seguito.The example demonstrates this.

EsempioExample

La query seguente SELECT recupera informazioni sulla categoria e sulla sottocategoria di un prodotto dal database AdventureWorks2012AdventureWorks2012 .The following SELECT query retrieves product category and subcategory information in the AdventureWorks2012AdventureWorks2012 database. La query non include istruzioni FOR XML nidificate.There is no nested FOR XML in the query.

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:This is the partial result:

<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 nella query si specifica la direttiva ELEMENTS , verrà restituito un risultato incentrato sugli elementi, come illustrato nel frammento di risultato seguente:If you specify the ELEMENTS directive in the query, you receive an element-centric result, as shown in the following result fragment:

<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 costituita da una combinazione di valori XML incentrati sugli elementi e incentrati sugli attributi, come illustrato nel frammento seguente:Next, assume that you want to generate an XML hierarchy that is a combination of attribute-centric and element-centric XML, as shown in the following fragment:

<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 il nome e l'ID della categoria, sono attributi.In the previous fragment, product category information such as category ID and category name are attributes. Tuttavia, le informazioni sulla sottocategoria sono incentrate sugli elementi.However, the subcategory information is element-centric. Per costruire l'elemento <ProductCategory> è possibile creare una query FOR XML, come illustrato di seguito:To construct the <ProductCategory> element, you can write a FOR XML query as shown in the following:

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

Risultato:This is the result:

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

Per costruire gli elementi <ProductSubCategory> nidificati nel valore XML, è quindi necessario aggiungere una query FOR XML nidificata, come illustrato di seguito:To construct the nested <ProductSubCategory> elements in the XML you want, you then add a nested FOR XML query, as shown in the following:

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:Note the following in the previous query:

  • La query FOR XML interna recupera informazioni sulla sottocategoria del prodotto.The inner FOR XML query retrieves product subcategory information. Nella query ELEMENTS interna viene aggiunta la direttiva FOR XML per generare un valore XML incentrato sugli elementi, che verrà aggiunto al valore XML generato dalla query esterna.The ELEMENTS directive is added in the inner FOR XML to generate element-centric XML that is added to the XML generated by the outer query. Per impostazione predefinita la query esterna genera un valore XML incentrato sugli attributi.By default, the outer query generates attribute-centric XML.

  • Nella query interna è specificata la direttiva TYPE in modo che venga restituito un risultato di tipo xml .In the inner query, the TYPE directive is specified so the result is of xml type. Se la direttiva TYPE non viene specificata, verrà restituito un risultato di tipo nvarchar(max) e i dati XML verranno restituiti come entità.If TYPE is not specified, the result is returned as nvarchar(max) type and the XML data is returned as entities.

  • Poiché la direttiva TYPE è specificata anche nella query esterna,The outer query also specifies the TYPE directive. il risultato della query verrà restituito al client come tipo xml .Therefore, the result of this query is returned to the client as xml type.

    Risultato parziale:This is the partial result:

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

La query seguente è semplicemente un'estensione della precedente.The following query is just an extension of the previous query. Visualizza la gerarchia dei prodotti completa nel database AdventureWorks2012AdventureWorks2012 ,It shows the full product hierarchy in the AdventureWorks2012AdventureWorks2012 database. Sono inclusi gli elementi seguenti:This includes the following:

  • Categorie di prodottiProduct categories

  • Sottocategorie di prodotti in ogni categoriaProduct subcategories in each category

  • Modelli di prodotti in ogni sottocategoriaProduct models in each subcategory

  • Prodotti per ogni modelloProducts in each model

    Per comprendere l'organizzazione del database AdventureWorks2012AdventureWorks2012 , è possibile utilizzare la query seguente:You might find the following query useful in understanding the AdventureWorks2012AdventureWorks2012 database:

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:This is the partial result:

<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 FOR XML nidificata che genera le sottocategorie di prodotti, il risultato sarà interamente incentrato sugli attributi.If you remove the ELEMENTS directive from the nested FOR XML query that generates product subcategories, the whole result is attribute-centric. È pertanto possibile scrivere questa query senza nidificazione.You can then write this query without nesting. L'aggiunta della direttiva ELEMENTS consente di ottenere un valore XML incentrato in parte sugli attributi ed in parte sugli elementi.The addition of ELEMENTS results in an XML that is partly attribute-centric and partly element-centric. Questo tipo di risultato non può essere generato da una query FOR XML con un solo livello.This result cannot be generated by a single-level, FOR XML query.

Vedere ancheSee Also

Utilizzo di query FOR XML nidificateUse Nested FOR XML Queries