提取相关 XML 组件

Extracting Related XML Component

我在下面 XML 中成功导出了 cmpD 节点的所有值。然而,我遇到困难的地方是如何提取出现在适当 dtl 节点中的相关 <bend> 值。

这是当前生成的结果:

当前结果

cmp cmpAmt  cmpCode
B   1       A
C   9       A
G   2       A
F   1       A
F   1       L

这是我试图获得的结果,但在 <Dtl>.

内具有适当的 <bend>

有谁知道如何做到这一点?

预期结果

cmp cmpAmt  cmpCode    bend
B   1       A          A 
C   9       A          A 
G   2       A          A
F   1       A          Z
F   1       L          Z

我目前拥有的:

DECLARE @XML XML = '
            <Dtl>
                <Type>R</Type>          
                <bend>A</bend>
                <cmpD>
                    <cmp>B</cmp>
                    <cmpAmt>1</cmpAmt>
                    <cmpCode>A</cmpCode>
                </cmpD>
                <cmpD>
                    <cmp>C</cmp>
                    <cmpAmt>9</cmpAmt>
                    <cmpCode>A</cmpCode>
                </cmpD>
                <cmpD>
                    <cmp>G</cmp>
                    <cmpAmt>2</cmpAmt>
                    <cmpCode>A</cmpCode>
                </cmpD>
            </Dtl>
            <Dtl>
                <Type>R</Type>
                <bend>Z</bend>
                <cmpD>
                    <cmp>F</cmp>
                    <cmpAmt>1</cmpAmt>
                    <cmpCode>A</cmpCode>
                </cmpD>
                <cmpD>
                    <cmp>F</cmp>
                    <cmpAmt>1</cmpAmt>
                    <cmpCode>L</cmpCode>
                </cmpD>
            </Dtl>'     

和 SQL:

select 
    b.value('(cmp/text())[1]','nvarchar(max)'),
    b.value('(cmpAmt/text())[1]','nvarchar(max)'),
    b.value('(cmpCode/text())[1]','nvarchar(max)')
from
    @XML.nodes('/Dtl/cmpD') AS A(b)

您可以先切碎 DTL 节点,然后将其送入另一个 .nodes 使用 cross apply 切碎 cmpD 节点:

select
    x2.cmpD.value('(cmp/text())[1]','nvarchar(max)'),
    x2.cmpD.value('(cmpAmt/text())[1]','nvarchar(max)'),
    x2.cmpD.value('(cmpCode/text())[1]','nvarchar(max)'),
    x1.dtl.value('(bend/text())[1]','nvarchar(max)')
from
    @XML.nodes('/Dtl') x1(dtl)
cross apply x1.dtl.nodes('cmpD') AS x2(cmpD);

db<>fiddle

请注意第二个 .nodes 是如何引用第一个的,并且 不是 使用前导 /.

I suggest you rethink the column types and lengths, can they all really need nvarchar(max)?