【问题标题】:How to parse XML data in pipe delimited format and insert into table如何以管道分隔格式解析 XML 数据并插入到表中
【发布时间】:2018-04-20 15:53:04
【问题描述】:
<Status>SUCCESS</Status>
<Count>7</Count>
<Data>
    <Content>S|123|03011990|5236158|19901254189684|</Content>
    <Content>S|456|02011991|2584959|19916584159385|</Content>
</Data>

我需要解析数据并插入到表中。

INSERT INTO ins_data(TYPE,VNO,F_DATE,F_NO,F_CNO)。

我想在查询表格时看到如下输出。

S 123 03011990 5236158 19901254189684

S 456 02011991 2584959 19916584159385

【问题讨论】:

  • 好吧,你试过什么? SO 不是免费的编码服务。你需要付出一些努力。
  • 我尝试过这样的事情,但我得到 null SELECT TRIM(EXTRACTVALUE(column_value,'/Root/Status/Count/Content')) FROM TABLE(XMLSEQUENCE(EXTRACT(XMLTYPE(' SUCCESS7S|123|03011990|5236158|19901254189684|S|456|02011991|2584959|19916584159385|'),'/Root/Status')))

标签: oracle plsql xml-parsing xmltype extract-value


【解决方案1】:

这个查询有很多内容,所以我将逐步解释它。这是完整的查询:

with D as
(select xmltype('<Root>
<Status>SUCCESS</Status>
<Count>7</Count>
<Data>
    <Content>S|123|03011990|5236158|19901254189684|</Content>
    <Content>S|456|02011991|2584959|19916584159385|</Content>
</Data>
</Root>') dataStr from dual)

select *
from(
    select id, trim(column_value) text,
           rank() over(partition by id order by rownum) pos
    from(
        select rownum id, extract(column_value, 'Content/text()') text
        from d,
        table(xmlsequence(extract(dataStr,'Root/Data/*'))) x
    ),
    xmltable(('"' || REPLACE(text, '|', '","') || '"'))
)pivot(
    max(text) for pos in (1 as TYPE, 2 as VNO, 3 as F_DATE, 4 as F_NO, 5 as F_CNO)
)

我的 with 子句是使用 xmltype 命令将 xml 字符串转换为 xml 数据。

下一个是这个:

select rownum id, extract(column_value, 'Content/text()') text
  from d,
  table(xmlsequence(extract(dataStr,'Root/Data/*'))) x

这使用 xmlsequence 命令从 XML 中的对象中提取行。我使用rownum为每一行分配一个ID。稍后我将需要该字段。

下一部分是我从this site 那里学到的一个绝妙技巧

select id, trim(column_value) text,
           rank() over(partition by id order by rownum) pos
    from(
        select rownum id, extract(column_value, 'Content/text()') text
        from d,
        table(xmlsequence(extract(dataStr,'Root/Data/*'))) x
    ),
    xmltable(('"' || REPLACE(text, '|', '","') || '"'))

它使用 XML 表命令和 REPLACE 函数使用分隔符“|”分割每个值。我在值周围使用了 trim 命令,以便将 XML 数据转换为字符串。我还使用排名窗口函数以便在下一步中进行调整。

最后是这样的:

select *
from(
    select id, trim(column_value) text,
           rank() over(partition by id order by rownum) pos
    from(
        select rownum id, extract(column_value, 'Content/text()') text
        from d,
        table(xmlsequence(extract(dataStr,'Root/Data/*'))) x
    ),
    xmltable(('"' || REPLACE(text, '|', '","') || '"'))
)pivot(
    max(text) for pos in (1 as TYPE, 2 as VNO, 3 as F_DATE, 4 as F_NO, 5 as F_CNO)
)

我以我在上一步中创建的“pos”排名列为轴,并为每个部分指定您指定的列名称。

我的最终结果如下所示:

ID  TYPE    VNO     F_DATE      F_NO        F_CNO
1   S       123     03011990    5236158     19901254189684
2   S       456     02011991    2584959     19916584159385

【讨论】:

  • 非常感谢您抽出宝贵时间编写查询并向我详细解释。但它听起来有点复杂,我正在寻找简单的东西。不使用分区就不能写查询吗?
  • 随时等待其他人回复。我不认为你问的问题可以简单地处理。
  • 一个问题是我的数据中会有特殊字符。
  • 在你原来的问题中很高兴知道。
  • 如果浪费了您的时间,我真的很抱歉。
猜你喜欢
  • 1970-01-01
  • 2012-10-10
  • 2010-11-03
  • 1970-01-01
  • 2011-10-18
  • 2012-04-29
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多