本主题将单级 FOR XML 查询与嵌套 FOR XML 查询进行比较。 使用嵌套 FOR XML 查询的好处之一是,可以为查询结果指定以属性为中心的 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 和以元素为中心的 XML 的组合,如以下片段所示:
<ProductCategory ProductCategoryID="1" CategoryName="Bike">
<ProductSubCategory>
<ProductSubCategoryID>1</ProductSubCategoryID>
<SubCategoryName>Mountain Bike</SubCategoryName></ProductSubCategory>
<ProductSubCategory>
...
<ProductSubCategory>
...
</ProductCategory>
在前面的片段中,产品类别信息(如类别 ID 和类别名称)是属性。 但是,子类别信息以元素为中心。 若要构造 <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 查询生成。