共用方式為


FOR XML 查詢與巢狀 FOR XML 查詢的比較

本主題比較單一層級 FOR XML 查詢與巢狀 FOR XML 查詢。 使用巢狀 FOR XML 查詢的優點之一,就是您可以針對查詢結果指定以屬性為主和元素為中心的 XML 組合。 此範例說明了這一點。

範例

下列 SELECT 查詢會擷取 AdventureWorks2012 資料庫中的產品類別和子類別資訊。 查詢中不存在巢狀 FOR XML。

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  

以下是部份結果:

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

如果您在查詢中指定 ELEMENTS 指示詞,您會收到以元素為中心的結果,如下列結果片段所示:

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

接下來,假設您想要產生 XML 階層,該階層是屬性中心與元素中心 XML 的組合,如下列片段所示:

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

在上一個片段中,類別標識元和類別名稱等產品類別資訊是屬性。 不過,子類別資訊是以元素為中心的。 若要建構 <ProductCategory> 專案,您可以撰寫 FOR XML 查詢,如下所示:

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

以下是結果:

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

若要在您想要的 XML 中建構巢狀 <ProductSubCategory> 元素,然後新增巢狀 FOR XML 查詢,如下所示:

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  

請注意上一個查詢中的下列內容:

  • 內部 FOR XML 查詢會擷取產品子類別資訊。 將指令 ELEMENTS 新增至內部 FOR XML 指令,以產生以元素為中心的 XML,並將此 XML 新增至外部查詢產生的 XML。 根據預設,外部查詢會產生以屬性為中心的 XML。

  • 在內部查詢中,會指定 TYPE 指令,使結果為 xml 類型。 如果未 TYPE 指定,結果會以 nvarchar(max) 類型傳回,並以實體的形式傳回 XML 數據。

  • 外部查詢也會指定 TYPE 指示詞。 因此,此查詢的結果會以 xml 類型傳回給用戶端。

以下是部份結果:

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

下列查詢只是上一個查詢的延伸模組。 它會顯示 AdventureWorks2012 資料庫中的完整產品階層。 這包括下列項目:

  • 產品類別目錄

  • 每個類別中的產品子類別

  • 每個子類別中的產品模型

  • 每個模型中的產品

您可能會發現下列查詢有助於瞭解 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  

以下是部份結果:

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

如果您從產生產品子類別的巢狀FOR XML查詢中移除 ELEMENTS 指示詞,則整個結果會以屬性為主。 接著,您可以撰寫此查詢,而不需要使用巢狀結構。 將 ELEMENTS 加入會生成一個部分以屬性為中心、部分以元素為中心的 XML。 此結果無法由單一層級 FOR XML 查詢產生。

另請參閱

使用巢狀 FOR XML 查詢