选择XML节点和表值

时间:2012-10-26 15:39:08

标签: sql xml tsql

我们有一个表,其中包含描述由远程函数发送的一组订单的XML。当订单列表到达我们的系统时,每一行还包含ID,时间戳等内容。

举例说明:

id | date                     | XML 
1    2012-10-20 06:51:13.683   <customer name="Bill"><order oId="1">...</order><order oId="2>...</customer>
2    2012-10-20 07:30:32.833   <customer name="Ben"><order oId="23">...</order></customer>

我想选择所有订单,但我也希望每个订单都与它的ID和日期一起选择。一些假设的结果:

 id   |  date                  |  Customer | OrderId
 1      2012-10-20 06:51:13.683    Bill       1
 1      2012-10-20 06:51:13.683    Bill       2
 2      2012-10-20 06:51:13.683    Ben        23

环顾四周,我发现了许多答案,例如Select XML nodes using TSQL,但这些只涉及选择节点的第一个实例。我想选择每个订单节点以及与之关联的其他表信息。

感谢。

4 个答案:

答案 0 :(得分:2)

您必须更新列的名称,但这是我使用的方法:

SELECT xmlviewId, myDate
   , myXml.value('(customer[1]/@name)', 'varchar(10)') AS CustomerName
   , orders.value('@oId', 'VARCHAR(10)') AS OrderId
   , orders.value('../@name', 'VARCHAR(10)') AS AlternateWayToGEtCustomerName
FROM xmlView
CROSS APPLY myXml.nodes('//order') AS c(orders);

SQL Fiddle示例

这是xquery value

的一个很好的例子

我添加了另一种获取customerName的方法,具体取决于您的偏好。

答案 1 :(得分:2)

SQL Fiddle Example

我认为在两个应用中做到这一点更合乎逻辑

select
    tt.id,
    tt.date,
    cust.col.value('@name', 'nvarchar(128)') as Customer,
    ord.col.value('@oId', 'int') as OrderId
from tt as tt
    outer apply tt.[xml].nodes('/customer') as cust(col)
    outer apply cust.col.nodes('order') as ord(col)

但您也可以在一次申请

中完成

SQL Fiddle Example

select
    tt.id,
    tt.date,
    ord.col.value('../@name', 'nvarchar(128)') as Customer,
    ord.col.value('@oId', 'int') as OrderId
from tt as tt
    outer apply tt.[xml].nodes('/customer/order') as ord(col)

答案 2 :(得分:0)

我认为this正是您所寻找的

答案 3 :(得分:0)

您可以使用@指定属性,因此您的查询将是这样的:

DECLARE @T TABLE (ID INT, [Date] DATETIME, [XML] XML);
INSERT @T VALUES 
    (1, '20121020 06:51:13.683', '<customer name="Bill"><order oId="1"></order><order oId="2"></order></customer>'),
    (2, '20121020 07:30:32.833', '<customer name="Ben"><order oId="23"></order></customer>');

SELECT  ID,
        [Date],
        [Customer] = [XML].value('(customer/@name)[1]', 'nvarchar(200)'),
        [OrderID] = t.Orders.value('(@oId)[1]', 'int')
FROM    @T
        CROSS APPLY [XML].nodes('/customer/order') t (Orders)