1

在从 XML 中提取记录并将其加载到 SQL Server 表中时,我需要进一步的帮助。

我有这个作为我的@xml

<admin submitter_id="login0" effective_date="mm/dd/yyyy">
<rec effected_id="login1" adjustment="100.00" type="foo">
<reason reason_id="1" />
<reason reason_id="2" />
</rec>
<rec effected_id="login2" adjustment="50.00" type="bar">
<reason reason_id="3" />
</rec>
</admin>

我需要一个结果集中的这个:

login0, login1, mm/dd/yyyy, 100.00, foo, 1
login0, login1, mm/dd/yyyy, 100.00, foo, 2
login0, login2, mm/dd/yyyy, 50.00, bar, 3

那有意义吗?对 reason_id 的调整是一对多的。我已经想出了如何提取除第二行之外的所有值。我只能获取第一个reason_id,然后继续下一条记录。我认为这可以通过 CROSS APPLY 来解决,但我无法让它发挥作用。请帮忙!

哦,我可能也收到了伪造的 XML。所以如果错了,请告诉我!

4

2 回答 2

1

像这样的东西怎么样

DECLARE @Xml XML

SELECT @Xml = '<admin submitter_id="login0" effective_date="mm/dd/yyyy"> 
<rec effected_id="login1" adjustment="100.00" type="foo"> 
<reason reason_id="1" /> 
<reason reason_id="2" /> 
</rec> 
<rec effected_id="login2" adjustment="50.00" type="bar"> 
<reason reason_id="3" /> 
</rec> 
</admin>'

SELECT  @Xml,
        A2.B.value('(../../@submitter_id)[1]','VARCHAR(50)'),
        A2.B.value('(../@effected_id)[1]','VARCHAR(50)'),
        A2.B.value('(../../@effective_date)[1]','VARCHAR(50)'),
        A2.B.value('(../@adjustment)[1]','FLOAT'),
        A2.B.value('(../@type)[1]','VARCHAR(50)'),
        A2.B.value('(@reason_id)[1]','INT')
FROM    @XML.nodes('//admin/rec/reason')  A2(B)

SQL 小提琴演示

于 2012-10-08T05:00:11.233 回答
0

尝试使用这个 T-SQL 代码片段:

SELECT
    Submitter = @xml.value('(/admin/@submitter_id)[1]', 'varchar(50)'),
    EffectedID = Rec.value('(@effected_id)[1]', 'varchar(50)'),
    DateStamp = @xml.value('(/admin/@effective_date)[1]', 'varchar(50)'),
    TypeID = Rec.value('(@type)[1]', 'varchar(50)'),
    ReasonID = Reason.value('(@reason_id)[1]', 'int')
FROM
    @xml.nodes('/admin/rec') AS Tbl(Rec)
CROSS APPLY
    Rec.nodes('reason') AS T2(Reason)

它给了我一个输出:

在此处输入图像描述

您需要有两个嵌套的节点列表 - 第一个<rec>从内部获取所有节点<admin>,而第二个迭代<reason>每个节点内的所有<rec>节点。这样,您可以可靠地从这两个嵌套级别的子节点中提取所有信息,无论每个级别上有多少子节点。

于 2012-10-08T04:58:28.300 回答