我们有一个表,其中包含描述由远程函数发送的一组订单的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,但这些只涉及选择节点的第一个实例。我想选择每个订单节点以及与之关联的其他表信息。
感谢。
答案 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);
这是xquery value
的一个很好的例子我添加了另一种获取customerName的方法,具体取决于您的偏好。
答案 1 :(得分:2)
我认为在两个应用中做到这一点更合乎逻辑
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)
但您也可以在一次申请
中完成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)