使用嵌套 AUTO 模式查询生成同级

以下示例演示如何使用嵌套 AUTO 模式查询生成同级。 生成此类 XML 的唯一方法是使用 EXPLICIT 模式。 但是,这可能很麻烦。

示例:

此查询构造提供销售订单信息的 XML。 其中包括:

  • 销售订单标头信息、SalesOrderIDSalesPersonIDOrderDateAdventureWorks2012 将此信息 SalesOrderHeader 存储在表中。

  • 销售订单详细信息。 这包括订购的一个或多个产品、单价和订购数量。 此信息存储在 SalesOrderDetail 表中。

  • 销售人员信息。 这是负责接订单的销售人员。 该 SalesPerson 表提供了 SalesPersonID. 对于此查询,必须将此表联接到 Employee 表中才能查找销售人员的名称。

接下来的两个不同的 SELECT 查询生成在形状上稍有差异的 XML。

第一个查询生成 XML,其中 <SalesPerson> 和 <SalesOrderHeader> 显示为 <SalesOrder> 的并列子级。

SELECT   
      (SELECT top 2 SalesOrderID, SalesPersonID, CustomerID,  
         (select top 3 SalesOrderID, ProductID, OrderQty, UnitPrice  
           from Sales.SalesOrderDetail  
            WHERE  SalesOrderDetail.SalesOrderID =   
                   SalesOrderHeader.SalesOrderID  
            FOR XML AUTO, TYPE)  
        FROM  Sales.SalesOrderHeader  
        WHERE SalesOrderHeader.SalesOrderID = SalesOrder.SalesOrderID  
        for xml auto, type),  
        (SELECT *   
         FROM  (SELECT SalesPersonID, EmployeeID  
              FROM Sales.SalesPerson, HumanResources.Employee  
              WHERE SalesPerson.SalesPersonID = Employee.EmployeeID) As   
                     SalesPerson  
         WHERE  SalesPerson.SalesPersonID = SalesOrder.SalesPersonID  
       FOR XML AUTO, TYPE)  
FROM (SELECT SalesOrderHeader.SalesOrderID, SalesOrderHeader.SalesPersonID  
      FROM Sales.SalesOrderHeader, Sales.SalesPerson  
      WHERE SalesOrderHeader.SalesPersonID = SalesPerson.SalesPersonID  
     ) as SalesOrder  
ORDER BY SalesOrder.SalesOrderID  
FOR XML AUTO, TYPE  

在上一个查询中,最外层的 SELECT 语句执行以下操作:

  • 查询FROM子句中指定的SalesOrder行集。 结果是包含一个或多个 <SalesOrder> 元素的 XML。

  • 指定 AUTO 模式和 TYPE 指令。 AUTO 模式将查询结果转换为 XML,指令 TYPE 将返回结果作为 xml 类型。

  • 包括用逗号分隔的两个嵌套 SELECT 语句。 第一个嵌套 SELECT 检索销售订单信息、标题和详细信息,第二个嵌套 SELECT 语句检索销售人员信息。

    • SELECT语句检索SalesOrderIDSalesPersonIDCustomerID本身,并且包括返回销售订单详细信息的另一个嵌套SELECT ... FOR XML语句(具有AUTO模式和TYPE指令)。

SELECT语句检索销售人员信息,并查询在FROM子句中创建的行集SalesPerson。 为了使 FOR XML 查询正常工作,必须在 FROM 子句中为生成的匿名行集提供名称。 在这种情况下,提供的名称为 SalesPerson.

下面是部分结果:

<SalesOrder>  
  <Sales.SalesOrderHeader SalesOrderID="43659" SalesPersonID="279" CustomerID="676">  
    <Sales.SalesOrderDetail SalesOrderID="43659" ProductID="776" OrderQty="1" UnitPrice="2024.9940" />  
    <Sales.SalesOrderDetail SalesOrderID="43659" ProductID="777" OrderQty="3" UnitPrice="2024.9940" />  
    <Sales.SalesOrderDetail SalesOrderID="43659" ProductID="778" OrderQty="1" UnitPrice="2024.9940" />  
  </Sales.SalesOrderHeader>  
  <SalesPerson SalesPersonID="279" EmployeeID="279" />  
</SalesOrder>  
...  

以下查询生成相同的销售订单信息,只是生成的 XML 中,<SalesPerson>作为<SalesOrderDetail>的同级元素出现。

<SalesOrder>  
    <SalesOrderHeader ...>  
          <SalesOrderDetail .../>  
          <SalesOrderDetail .../>  
          ...  
          <SalesPerson .../>  
    </SalesOrderHeader>  
  
</SalesOrder>  
<SalesOrder>  
  ...  
</SalesOrder>  

以下是查询语句:

SELECT SalesOrderID, SalesPersonID, CustomerID,  
             (select top 3 SalesOrderID, ProductID, OrderQty, UnitPrice  
              from Sales.SalesOrderDetail  
              WHERE SalesOrderDetail.SalesOrderID = SalesOrderHeader.SalesOrderID  
              FOR XML AUTO, TYPE),  
              (SELECT *   
               FROM  (SELECT SalesPersonID, EmployeeID  
                    FROM Sales.SalesPerson, HumanResources.Employee  
                    WHERE SalesPerson.SalesPersonID = Employee.EmployeeID) As SalesPerson  
               WHERE  SalesPerson.SalesPersonID = SalesOrderHeader.SalesPersonID  
         FOR XML AUTO, TYPE)  
FROM Sales.SalesOrderHeader  
WHERE SalesOrderID=43659 or SalesOrderID=43660  
FOR XML AUTO, TYPE  

结果如下:

<Sales.SalesOrderHeader SalesOrderID="43659" SalesPersonID="279" CustomerID="676">  
  <Sales.SalesOrderDetail SalesOrderID="43659" ProductID="776" OrderQty="1" UnitPrice="2024.9940" />  
  <Sales.SalesOrderDetail SalesOrderID="43659" ProductID="777" OrderQty="3" UnitPrice="2024.9940" />  
  <Sales.SalesOrderDetail SalesOrderID="43659" ProductID="778" OrderQty="1" UnitPrice="2024.9940" />  
  <SalesPerson SalesPersonID="279" EmployeeID="279" />  
</Sales.SalesOrderHeader>  
<Sales.SalesOrderHeader SalesOrderID="43660" SalesPersonID="279" CustomerID="117">  
  <Sales.SalesOrderDetail SalesOrderID="43660" ProductID="762" OrderQty="1" UnitPrice="419.4589" />  
  <Sales.SalesOrderDetail SalesOrderID="43660" ProductID="758" OrderQty="1" UnitPrice="874.7940" />  
  <SalesPerson SalesPersonID="279" EmployeeID="279" />  
</Sales.SalesOrderHeader>  

TYPE由于指令以类型形式xml返回查询结果,因此可以使用各种xml数据类型方法查询生成的 XML。 有关详细信息,请参阅 xml 数据类型方法。 在以下查询中,请注意以下事项:

  • 将先前的查询添加到 FROM 子句中。 查询结果以表的形式返回。 请注意添加的 XmlCol 别名。

  • SELECT 子句指定了针对 FROM 子句中返回的 XmlCol 的 XQuery。 数据类型 query() 的方法 xml 用于指定 XQuery。 有关详细信息,请参阅 query() 方法(xml 数据类型)。

    SELECT XmlCol.query('<Root> { /* } </Root>')  
    FROM (  
    SELECT SalesOrderID, SalesPersonID, CustomerID,  
                 (select top 3 SalesOrderID, ProductID, OrderQty, UnitPrice  
                  from Sales.SalesOrderDetail  
                  WHERE SalesOrderDetail.SalesOrderID = SalesOrderHeader.SalesOrderID  
                  FOR XML AUTO, TYPE),  
                  (SELECT *   
                   FROM  (SELECT SalesPersonID, EmployeeID  
                        FROM Sales.SalesPerson, HumanResources.Employee  
                        WHERE SalesPerson.SalesPersonID = Employee.EmployeeID) As SalesPerson  
                   WHERE  SalesPerson.SalesPersonID = SalesOrderHeader.SalesPersonID  
             FOR XML AUTO, TYPE)  
    FROM Sales.SalesOrderHeader  
    WHERE SalesOrderID='43659' or SalesOrderID='43660'  
    FOR XML AUTO, TYPE ) as T(XmlCol)  
    

另请参阅

使用嵌套 FOR XML 查询