0
<Status>SUCCESS</Status>
<Count>7</Count>
<Data>
    <Content>S|123|03011990|5236158|19901254189684|</Content>
    <Content>S|456|02011991|2584959|19916584159385|</Content>
</Data>

I need to parse the data and insert into table.

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

I want to see the output like below when i query the table.

S 123 03011990 5236158 19901254189684

S 456 02011991 2584959 19916584159385

newbie
  • 75
  • 1
  • 8
  • 4
    OK well what have you tried? SO is not a free coding service. You need to show some effort. – OldProgrammer Apr 20 '18 at 16:22
  • i tried something like this, but i get null SELECT TRIM(EXTRACTVALUE(column_value,'/Root/Status/Count/Content')) FROM TABLE(XMLSEQUENCE(EXTRACT(XMLTYPE(' SUCCESS 7 S|123|03011990|5236158|19901254189684| S|456|02011991|2584959|19916584159385| '),'/Root/Status'))) – newbie Apr 20 '18 at 18:04

1 Answers1

3

There is a lot going on in this query so I will explain it in steps. This is the full query:

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)
)

My with clause is using the xmltype command to turn the xml string into xml data.

The next piece is this one:

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

This uses the xmlsequence command to extract the rows from the object in the XML. I am assigning each row an ID using rownum. I will need that field later.

The next part is a nifty trick I picked up from 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, '|', '","') || '"'))

It uses the XML table command and REPLACE function to split each value using the delimiter of "|". I use the trim command around the value in order to convert the XML data to strings. I also use a rank windowing function in order to pivot on in the next step.

The final part is this:

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)
)

I pivot on the "pos" rank column I made in the last step and give each piece the column name you indicated.

My final results look like this:

ID  TYPE    VNO     F_DATE      F_NO        F_CNO
1   S       123     03011990    5236158     19901254189684
2   S       456     02011991    2584959     19916584159385
Patrick H
  • 653
  • 6
  • 14
  • I really thank you for your time in writing the query and explaining to me in detail. But its sounds a bit complicated, i'm looking for something simple. Can't we write the query without using partition? – newbie Apr 20 '18 at 19:23
  • Feel free to wait for someone else to respond. I don't think the question you are asking can be handled simply. – Patrick H Apr 20 '18 at 19:35
  • one problem is i will have special characters in the data. – newbie Apr 20 '18 at 19:54
  • 1
    That would have been nice to know in your original question. – Patrick H Apr 20 '18 at 20:06
  • i really apologize if it would have wasted your time. – newbie Apr 20 '18 at 20:21