簡體   English   中英

粉碎嵌套的 XML 數據並返回集合

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM