Tsql OPENXML省略了没有指定元素的xml行

Tsql OPENXML省略了没有指定元素的xml行,tsql,sql-server-2012,Tsql,Sql Server 2012,我在SQL Server 2014 Server上运行下面的查询,但我不明白为什么我只得到一行结果 DECLARE @idoc int, @doc varchar(1000); SET @doc =' <ROOT> <Customer CustomerID="VINET" ContactName="Paul Henriot"> <Order CustomerID="VINET" EmployeeID="5" OrderDate="1996-

我在SQL Server 2014 Server上运行下面的查询,但我不明白为什么我只得到一行结果

DECLARE @idoc int, @doc varchar(1000);   

SET @doc ='  
<ROOT>  
<Customer CustomerID="VINET" ContactName="Paul Henriot">  
   <Order CustomerID="VINET" EmployeeID="5" OrderDate="1996-07-04T00:00:00">  
      <OrderDetail OrderID="10248" ProductID="11" Quantity="12"/>  
      <OrderDetail OrderID="10248" ProductID="42" Quantity="10">
                    <ReturnDetail ReturnOrderID="1111" ReturnDate="1996-08-04T00:00:00"/>
            </OrderDetail>  
   </Order>  
</Customer>  
<Customer CustomerID="LILAS" ContactName="Carlos Gonzlez">  
   <Order CustomerID="LILAS" EmployeeID="3" OrderDate="1996-08-16T00:00:00">  
      <OrderDetail OrderID="10283" ProductID="72" Quantity="3"/>  
   </Order>  
</Customer>  
</ROOT>';  

--Create an internal representation of the XML document.  
EXEC sp_xml_preparedocument @idoc OUTPUT, @doc;   

-- SELECT stmt using OPENXML rowset provider  
SELECT *  
FROM   OPENXML (@idoc, '/ROOT/Customer/Order/OrderDetail/ReturnDetail',2)   
         WITH ( OrderID       int         '../@OrderID',   
                order_CustomerID  varchar(10) '../../@CustomerID',   
                EmployeeID  varchar(10) '../../@EmployeeID',
                ContactName  varchar(100) '../../../@ContactName',
                CustomerID  varchar(10) '../../@CustomerID',
                OrderDate   datetime    '../../@OrderDate',   
                ProdID      int         '../@ProductID',   
                Qty         int         '../@Quantity',
                ReturnOrderID int '@ReturnOrderID',
                ReturnDate datetime '@ReturnDate'
                );
我怎样才能像下面这样返回所有3条记录

您应该使用内置的本机XQuery支持,而不是传统的OPENXML支持

使用此代码获取节点的所有详细信息,并将@doc变量定义为XML:

对于可能包含多个节点(如under等)的每个级别,您需要使用交叉应用和.nodes XQuery函数来获取所有子节点,而不仅仅是一个子节点或任意子节点。

您应该使用内置的本机XQuery支持,而不是传统的OPENXML支持

使用此代码获取节点的所有详细信息,并将@doc变量定义为XML:


对于可能包含多个节点(如under等)的每个级别,您需要使用交叉应用和.nodes XQuery函数来获取所有子节点,而不仅仅是一个或任意的子节点。

您的速度更快:-,+1。您可以添加ReturnOderID=XOD.value'ReturnDetail/@ReturnOrderID[1],'int'以获取较低的ReturnDetail节点的值,这些值可能不是1:n@Shnugo:太好了!最后的提示救了我一天谢谢,伙计!您好,我刚刚检查了您的编辑,发现您是如何处理CROSS APPLY的内部连接行为的。这是相同的,甚至更好的情况下,1:n使用外部应用。这会表现得像左撇子一样。谢谢大家!u是否表示OPENXML将在未来版本中被弃用?在TSQL中创建一个通用的XML到行转换器时,我特别希望使用开放XML。每次输入的XML可能包含相同数量的元素/属性,也可能不包含相同数量的元素/属性;客户不高兴听到我们可能不得不在这些情况下重新编码。但是,您的回答帮助我修复了原始查询代码ReturnOrderID int'ReturnDetail/@ReturnOrderID',ReturnDate datetime'ReturnDetail/@ReturnDate'@JayeshPrakash关于一般分解未知XML的问题。我有一个答案是指向OPENXML,它有一些非常罕见但仍然有用的领域,并且使用现代方法具有强大的功能。也许,这个函数就是你所需要的…你更快了:-,+1从我这边。您可以添加ReturnOderID=XOD.value'ReturnDetail/@ReturnOrderID[1],'int'以获取较低的ReturnDetail节点的值,这些值可能不是1:n@Shnugo:太好了!最后的提示救了我一天谢谢,伙计!您好,我刚刚检查了您的编辑,发现您是如何处理CROSS APPLY的内部连接行为的。这是相同的,甚至更好的情况下,1:n使用外部应用。这会表现得像左撇子一样。谢谢大家!u是否表示OPENXML将在未来版本中被弃用?在TSQL中创建一个通用的XML到行转换器时,我特别希望使用开放XML。每次输入的XML可能包含相同数量的元素/属性,也可能不包含相同数量的元素/属性;客户不高兴听到我们可能不得不在这些情况下重新编码。但是,您的回答帮助我修复了原始查询代码ReturnOrderID int'ReturnDetail/@ReturnOrderID',ReturnDate datetime'ReturnDetail/@ReturnDate'@JayeshPrakash关于一般分解未知XML的问题。我有一个答案是指向OPENXML,它有一些非常罕见但仍然有用的领域,并且使用现代方法具有强大的功能。也许,这个函数就是你所需要的。。。
DECLARE @doc XML;

SET @doc = '......';

SELECT
    OrderID = XOD.value('@OrderID', 'int'),
    CustomerID = XCus.value('@CustomerID', 'varchar(20)'),
    ContactName = XCus.value('@ContactName', 'varchar(50)'),
    EmployeeID = XOrder.value('@EmployeeID', 'int'),
    OrderDate = XOrder.value('@OrderDate', 'datetime'),
    ProductID = XOD.value('@ProductID', 'int'),
    Quantity = XOD.value('@Quantity', 'int'),
    ReturnOrderID = RetD.value('@ReturnOrderID', 'int'),
    ReturnDate = RetD.value('@ReturnDate', 'datetime')
FROM
    @doc.nodes('/ROOT/Customer') AS XT(XCus)
CROSS APPLY
    XCus.nodes('Order') AS XT2(XOrder)
CROSS APPLY
    XOrder.nodes('OrderDetail') AS XT3(XOD)
OUTER APPLY
    XOD.nodes('ReturnDetail') AS XT4(RetD)