Freigeben über


FOR XML-Abfragen im Vergleich zu geschachtelten FOR XML-Abfragen

In diesem Thema wird eine einstufige FOR XML-Abfrage mit einer geschachtelten FOR XML-Abfrage verglichen. Einer der Vorteile der Verwendung geschachtelter FOR XML-Abfragen besteht darin, dass Sie eine Kombination aus attributorientiertem und elementorientiertem XML für Abfrageergebnisse angeben können. Das Beispiel veranschaulicht dies.

Beispiel

Die folgende SELECT Abfrage ruft Produktkategorie- und Unterkategorieinformationen in der AdventureWorks2012-Datenbank ab. In der Abfrage ist kein geschachtelter FOR XML-Code vorhanden.

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  

Dies ist das Teilergebnis:

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

Wenn Sie die ELEMENTS Direktive in der Abfrage angeben, erhalten Sie ein elementorientiertes Ergebnis, wie im folgenden Ergebnisfragment dargestellt:

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

Gehen Sie als Nächstes davon aus, dass Sie eine XML-Hierarchie generieren möchten, die eine Kombination aus attributorientiertem und elementzentriertem XML ist, wie im folgenden Fragment dargestellt:

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

Im vorherigen Fragment sind Produktkategorieinformationen wie Kategorie-ID und Kategoriename Attribute. Die Unterkategorieinformationen sind jedoch elementzentriert. Um das <ProductCategory> Element zu erstellen, können Sie eine FOR XML Abfrage wie in der folgenden Abbildung gezeigt schreiben:

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

Dies ist das Ergebnis:

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

Um die geschachtelten <ProductSubCategory> Elemente im gewünschten XML-Code zu erstellen, fügen Sie dann eine geschachtelte FOR XML Abfrage hinzu, wie in den folgenden Beispielen gezeigt:

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  

Beachten Sie Folgendes in der vorherigen Abfrage:

  • Die innere FOR XML Abfrage ruft Produktunterkategorieinformationen ab. Die ELEMENTS Direktive wird im inneren FOR XML hinzugefügt, um elementorientierte XML zu generieren, die dem von der äußeren Abfrage generierten XML hinzugefügt wird. Standardmäßig generiert die äußere Abfrage attributorientierte XML.By default, the outer query generates attribute-centric XML.

  • In der inneren Abfrage wird die TYPE Direktive angegeben, sodass das Ergebnis vom XML-Typ ist. Wenn TYPE nicht angegeben, wird das Ergebnis als nvarchar(max) Typ zurückgegeben, und die XML-Daten werden als Entitäten zurückgegeben.

  • Die äußere Abfrage gibt auch die TYPE Direktive an. Daher wird das Ergebnis dieser Abfrage als XML-Typ an den Client zurückgegeben.

Dies ist das Teilergebnis:

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

Die folgende Abfrage ist nur eine Erweiterung der vorherigen Abfrage. Sie zeigt die vollständige Produkthierarchie in der AdventureWorks2012-Datenbank an. Hierzu gehören folgende Elemente:

  • Produktkategorien

  • Produktunterkategorien in jeder Kategorie

  • Produktmodelle in jeder Unterkategorie

  • Produkte in jedem Modell

Möglicherweise finden Sie die folgende Abfrage hilfreich, um die AdventureWorks2012-Datenbank zu verstehen:

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  

Dies ist das Teilergebnis:

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

Wenn Sie die ELEMENTS Direktive aus der geschachtelten FOR XML Abfrage entfernen, die Produktunterkategorien generiert, ist das gesamte Ergebnis attributorientiert. Sie können diese Abfrage dann ohne Schachtelung schreiben. Das Hinzufügen von ELEMENTS führt zu einem XML, das teils attributzentriert und teils elementzentriert ist. Dieses Ergebnis kann nicht von einer FOR-XML-Abfrage mit einer Ebene generiert werden.This result cannot be generated by a single-level, FOR XML query.

Siehe auch

Verwenden von geschachtelten FOR XML-Abfragen