将 AUTO 模式与 FOR XML 一起使用

FOR XML (SQL Server) 中所述,AUTO 模式将查询结果以嵌套 XML 元素的方式返回。 这不能较好地控制从查询结果生成的 XML 的形式。 如果要生成简单的层次结构,AUTO 模式查询很有用。 但是,将 EXPLICIT 模式与 FOR XML 一起使用将 PATH 模式与 FOR XML 一起使用在确定从查询结果生成的 XML 的形式方面可提供更好的控制和更大的灵活性。

在 FROM 子句内,每个在 SELECT 子句中至少有一列被列出的表都表示为一个 XML 元素。 如果在 FOR XML 子句中指定了可选的 ELEMENTS 选项,SELECT 子句中列出的列将映射到属性或子元素。

生成的 XML 中的 XML 层次结构(即元素嵌套)基于由 SELECT 子句中指定的列所标识的表的顺序。 因此,在 SELECT 子句中指定的列名的顺序非常重要。 最左侧第一个被标识的表形成所生成的 XML 文档中的顶级元素。 由 SELECT 语句中的列所标识的最左侧第二个表形成顶级元素内的子元素,依此类推。

如果 SELECT 子句中列出的列名来自由 SELECT 子句中以前指定的列所标识的表,该列将作为已创建的元素的属性添加,而不是在层次结构中打开一个新级别。 如果已指定 ELEMENTS 选项,该列将作为属性添加。

例如,执行以下查询:

SELECT Cust.CustomerID, 
       OrderHeader.CustomerID,
       OrderHeader.SalesOrderID, 
       OrderHeader.Status,
       Cust.CustomerType
FROM Sales.Customer Cust, Sales.SalesOrderHeader OrderHeader
WHERE Cust.CustomerID = OrderHeader.CustomerID
ORDER BY Cust.CustomerID
FOR XML AUTO

下面是部分结果:

<Cust CustomerID="1" CustomerType="S">
  <OrderHeader CustomerID="1" SalesOrderID="43860" Status="5" />
  <OrderHeader CustomerID="1" SalesOrderID="44501" Status="5" />
  <OrderHeader CustomerID="1" SalesOrderID="45283" Status="5" />
  <OrderHeader CustomerID="1" SalesOrderID="46042" Status="5" />
</Cust>
...

对于 SELECT 子句,注意下列内容:

  • CustomerID 引用 Cust 表。 因此,创建一个 <Cust> 元素,CustomerID 作为其属性添加。

  • 接下来的三列 OrderHeader.CustomerID、OrderHeader.SaleOrderID 和 OrderHeader.Status 引用 OrderHeader 表。 因此,为 <Cust> 元素添加 <OrderHeader> 子元素,这三列作为 <OrderHeader> 的属性添加。

  • 接着,Cust.CustomerType 列再次引用 Cust 表,该表已由 Cust.CustomerID 列标识。 因此,不创建新元素, 而是为以前创建的 <Cust> 元素添加 CustomerType 属性。

  • 查询为表名指定别名。 这些别名显示为相应的元素名。

  • 需要使用 ORDER BY 对一个父级下的所有子级分组。

下面的查询与上一个查询类似,不同的是 SELECT 子句先指定 OrderHeader 表中的列,再指定 Cust 表中的列。 因此,首先创建 <OrderHeader> 元素,然后为该元素添加 <Cust> 子元素。

select OrderHeader.CustomerID,
       OrderHeader.SalesOrderID, 
       OrderHeader.Status,
       Cust.CustomerID, 
       Cust.CustomerType
from Sales.Customer Cust, Sales.SalesOrderHeader OrderHeader
where Cust.CustomerID = OrderHeader.CustomerID
for xml auto

下面是部分结果:

<OrderHeader CustomerID="1" SalesOrderID="43860" Status="5">
  <Cust CustomerID="1" CustomerType="S" />
</OrderHeader>
...

如果在 FOR XML 子句中添加了 ELEMENTS 选项,将返回以元素为中心的 XML。

SELECT Cust.CustomerID, 
       OrderHeader.CustomerID,
       OrderHeader.SalesOrderID, 
       OrderHeader.Status,
       Cust.CustomerType
FROM Sales.Customer Cust, Sales.SalesOrderHeader OrderHeader
WHERE Cust.CustomerID = OrderHeader.CustomerID
ORDER BY Cust.CustomerID
FOR XML AUTO, ELEMENTS

下面是部分结果:

<Cust>
  <CustomerID>1</CustomerID>
  <CustomerType>S</CustomerType>
  <OrderHeader>
    <CustomerID>1</CustomerID>
    <SalesOrderID>43860</SalesOrderID>
    <Status>5</Status>
  </OrderHeader>
   ...
</Cust>
...

在此查询中,因为 CustomerID 是表的主键,所以在创建 <Cust> 元素的过程中会逐行比较 CustomerID 值。 如果未将 CustomerID 标识为表的主键,将逐行比较所有列值(此查询中的 CustomerID 和 CustomerType)。 如果值不同,将向 XML 添加新的 <Cust> 元素。

在比较这些列值时,如果要比较的任何列是 textntextimagexml 类型,即使它们的值可能相同,FOR XML 也将认为它们是不同的,并且不对其进行比较。 这是因为不支持大型对象的比较。 这些元素将被添加到每个选定行的结果中。 请注意,会比较 (n)varchar(max)varbinary(max) 类型的列。

如果 SELECT 子句中的某列无法与 FROM 子句中标识的任何表相关联(例如,该列是聚合列或计算列的情况下),则该列在列表中出现时,将添加到 XML 文档的最深嵌套级别中。 如果该列作为 SELECT 子句的第一列出现,将被添加到顶级元素。

如果 SELECT 子句中指定了星号 (*) 通配符,则以前面所述的方式根据查询引擎所返回的行的顺序确定嵌套。

本节内容

下面的主题提供有关 AUTO 模式的更多信息:

请参阅

参考

SELECT (Transact-SQL)

FOR XML (SQL Server)