0

我们有一个表,其中包含描述由远程函数发送的一组订单的 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

环顾四周,我找到了很多答案,例如使用 TSQL 选择 XML 节点,但这些仅涉及选择节点的第一个实例。我想选择每个订单节点以及与之关联的其他表信息。

谢谢。

4

4 回答 4

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 小提琴示例

这是 xquery值的一个很好的例子

我添加了第二种获取客户名称的方法,具体取决于您的偏好。

于 2012-10-26T16:17:37.477 回答
2

SQL 小提琴示例

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

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 小提琴示例

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)
于 2012-10-26T16:21:54.820 回答
0

我想就是你要找的

于 2012-10-26T16:10:06.893 回答
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)
于 2012-10-26T16:30:05.073 回答