[英]Shredding nested XML data and returning sets
我有 xml 數據,其中 collections 嵌套在多個級別中。
DECLARE @xml AS XML
SET @xml = '<periods xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<period>
<id>1</id>
<valid_from>2020-07-31</valid_from>
<valid_to xsi:nil="true" />
<elements>
<element>
<from>1</from>
<to>2</to>
</element>
<element>
<from>1</from>
<to>3</to>
</element>
</elements>
</period>
<period>
<id>3</id>
<valid_from>2020-05-01</valid_from>
<valid_to>2020-06-01</valid_to>
<elements>
<element>
<from>7</from>
<to>9</to>
</element>
<element>
<from>10</from>
<to>11</to>
</element>
</elements>
</period>
</periods>'
我想要的是把 select 所有這些數據轉換成表格:
id valid_from valid_to from to
1 2020-07-31 00:00:00.000 NULL 1 2
1 2020-07-31 00:00:00.000 NULL 1 3
3 2020-05-01 00:00:00.000 2020-06-01 00:00:00.000 7 9
3 2020-05-01 00:00:00.000 2020-06-01 00:00:00.000 10 11
我能得到的最接近的是這個查詢
SELECT 'id' = v.value('id[1]', 'int'),
'dte_from' = v.value('valid_from[1]', 'datetime'),
'dte_to' = v.value('valid_to[1][not(@xsi:nil = "true")]', 'datetime'),
'from' = y.value('from[1][not(@xsi:nil = "true")]', 'int'), 'to' = y.value('to[1]', 'int')
FROM @xml.nodes('/periods/period') x(v)
CROSS APPLY x.v.nodes('/periods/period/elements/element') z(y)
但這只是返回
id dte_from dte_to from to
1 2020-07-31 00:00:00.000 NULL 1 2
1 2020-07-31 00:00:00.000 NULL 1 3
1 2020-07-31 00:00:00.000 NULL 7 9
1 2020-07-31 00:00:00.000 NULL 10 11
3 2020-05-01 00:00:00.000 2020-06-01 00:00:00.000 1 2
3 2020-05-01 00:00:00.000 2020-06-01 00:00:00.000 1 3
3 2020-05-01 00:00:00.000 2020-06-01 00:00:00.000 7 9
3 2020-05-01 00:00:00.000 2020-06-01 00:00:00.000 10 11
感謝您的時間。
出於某種原因,您正在重新聲明CROSS APPLY
中的根節點。 你不需要這些,如果你刪除它們,你會得到你想要的結果:
SELECT pp.p.value('(id/text())[1]', 'int') AS id,
pp.p.value('(valid_from/text())[1]', 'datetime') AS dte_from,
pp.p.value('(valid_to[not(@xsi:nil = "true")]/text())[1]', 'datetime') AS dte_to,
ee.e.value('(from[1][not(@xsi:nil = "true")]/text())[1]', 'int') AS int_from, --don't use FROM, it's a reserve keyword,
ee.e.value('(to[1]/text())[1]', 'int') AS int_to --don't use TO, it's a reserve keyword,
FROM @xml.nodes('/periods/period') pp(p)
CROSS APPLY pp.p.nodes('elements/element') ee(e);
正如我的評論中提到的,不要使用'string_alias' = expression
,因為它將從 SQL 服務器中刪除,並且對列使用字符串別名可能會非常混亂。 我還為您的列和對象提供了更相關的別名,或者不是保留關鍵字的別名。
在從 XML 獲取值時,我還使用了text()
功能,因為這樣更快。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.