将 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 表。 因此,将元素<OrderHeader>添加为 元素的>Cust<子元素,并将这三列添加为 的属性。<OrderHeader>

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

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

  • 需要使用 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)