本主題比較單一層級 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 查詢產生。