DECLARE @hDoc XML =
'<orders>
<mail>
<set id="s" sequence="1" version="1.1" >
<set id="order" sequence="4" version="">
<property id="id" label="" sequence="0" resource_label="" show_type="" name="" ><![CDATA[€ 10000]]></property>
<set id="article" sequence="1" version="">
<property id="basepricevalue" label="" sequence="0" resource_label="" show_type="" name="" ><![CDATA[155.66]]></property>
<property id="quantity" label="" sequence="0" resource_label="" show_type="" name="" ><![CDATA[3]]></property>
<property id="senior" label="" sequence="0" resource_label="" show_type="" name="" ><![CDATA[16]]></property>
<property id="vat" label="" sequence="0" resource_label="" show_type="" name="" ><![CDATA[21]]></property>
</set>
<set id="article" sequence="2" version="">
<property id="basepricevalue" label="" sequence="0" resource_label="" show_type="" name="" ><![CDATA[465.99]]></property>
<property id="quantity" label="" sequence="0" resource_label="" show_type="" name="" ><![CDATA[12]]></property>
<property id="senior" label="" sequence="0" resource_label="" show_type="" name="" ><![CDATA[17]]></property>
<property id="vat" label="" sequence="0" resource_label="" show_type="" name="" ><![CDATA[18]]></property>
</set>
</set>
</set>
</mail>
</orders>';
期望的输出:
OrderID basepricevalue quantity senior vat
10000 155.66 3 16 21
10000 465.99 12 17 18
这就是我现在所拥有的,但由于所有的交叉应用,性能非常糟糕。我确信必须有更好的方法来做到这一点。
SELECT
orderid = nd.x.value('(property/text())[1]', 'varchar(8000)'),
price = ndprice.x.value('(text())[1]', 'varchar(100)'),
quantity = ndquantity.x.value('(text())[1]', 'varchar(100)'),
senior = ndsenior.x.value('(text())[1]', 'varchar(100)'),
vat = ndvat.x.value('(text())[1]', 'varchar(100)')
FROM (VALUES (@hDoc)) hdoc(orders)
CROSS APPLY orders.nodes('orders/mail//set[@id="order"]') nd(x)
CROSS APPLY x.nodes('set[@id="article"]') nd2(x)
CROSS APPLY nd2.x.nodes('property[@id="basepricevalue"]') ndprice(x)
CROSS APPLY nd2.x.nodes('property[@id="quantity"]') ndquantity(x)
CROSS APPLY nd2.x.nodes('property[@id="senior"]') ndsenior(x)
CROSS APPLY nd2.x.nodes('property[@id="vat"]') ndvat(x)
答案 0 :(得分:0)
你可以摆脱一些CROSS APPLY,因为你可以使用query()来获取某些元素
SELECT
orderid = O.orderset.query('property[@id="id"]/text()').value('.','varchar(max)'),
price = A.article.query('property[@id="basepricevalue"]/text()').value('.','float'),
quantity = A.article.query('property[@id="quantity"]/text()').value('.','int'),
senior = A.article.query('property[@id="senior"]/text()').value('.','int'),
vat = A.article.query('property[@id="vat"]/text()').value('.','int')
FROM (VALUES (@hDoc)) hdoc(orders)
CROSS APPLY orders.nodes('orders/mail//set[@id="order"]') O(orderset)
CROSS APPLY O.orderset.nodes('set[@id="article"]') A(article)
或者您确实可以使用更具体的xpath直接使用value() 并把它首次出现[1]。
此外,您可以通过直接从XML类型获取节点来摆脱额外的CROSS APPLY。
SELECT
orderid = O.orderset.value('(property[@id="id"]/text())[1]','varchar(max)'),
price = A.article.value('(property[@id="basepricevalue"]/text())[1]','float'),
quantity = A.article.value('(property[@id="quantity"]/text())[1]','int'),
senior = A.article.value('(property[@id="senior"]/text())[1]','int'),
vat = A.article.value('(property[@id="vat"]/text())[1]','int')
FROM @hDoc.nodes('orders/mail//set[@id="order"]') O(orderset)
CROSS APPLY O.orderset.nodes('set[@id="article"]') A(article)