xml - repeatable blocks with range in oracle -


please find below table. entire data within docstart , docend. data further enclosed within baccstart , baccend. type of block repeatable. have pick of abcd repeatable , total(occurring once per block) , accname (occurring once per block) each block within baccstart , baccend , form xml

<baccstart> <total>100</total> <abcd>abcd</abcd> <accname>name</accname> </baccstart> 

for each such block. presently using loop, performance not mark. have around 200 such blocks have form xmls within 15 seconds. presently loop taking around 53 secs.

rownum   name     value  1      docstart  null  2      baccstart null  3      abcd      abcd  4      abcd      abcd2  5      pqrs      pqrs  6      pqrs      pqrs2  7      total     100  8      accname   name  9      baccend   null  10     baccstart null  11     abcd      abcd  12     abcd      abcd2  13     pqrs      pqrs3  14     pqrs      pqrs4  15     total     150  16     accname   name  17     baccend   null  18     docend    null 

please me out this. if possible time effective query.

it oracle 10g.

i have across modification in requirement. value of accname present in cofig table of around 90 rows. there have pick 3 values value1 accname , corresponding value2 , value3 , populate tags in xml. if join table performance impact. please suggest. config table like

header1      header2        header3        header4 ........ <accname>    value2          value3 ............. ............. ............. ............. 

the data presented above, table contains long. after converting clob , using xmltable getting above data. better use global temporary table insert data before proceeding. like

insert  data(row_num,name,value) select /*+ no_xml_query_rewrite , parallel(x,8) */ rownum rn, substr(extractvalue(x.column_value,'/e'),1,instr(extractvalue(x.column_value,'/e'),' ')-1) name,  substr(extractvalue(x.column_value,'/e'),instr(extractvalue(x.column_value,'/e'),' ')+1)  value  dual, xmltable('e' passing xmltype('<e><e>' ||  replace(long2clob('select longdata billedacc order segment_number'),  '|'||chr(10), '</e><e>')    ||  '</e></e>').extract('e/e')                        ) x; 

also suggest if there better way handle this.

given 9000 data rows (500 * 18 sample rows provided above) following code runs in around second, should hit performance targets:

declare    l_xml_data xmltype;  begin    <<baccstart_loop>>   r_baccstart in (     -- initially, start/end rows     delimiters_all_rows (       select d.*       data d       d.name in ('baccstart', 'baccend')     )     -- lead on rows order row_num start/end pairs      -- single row     , delimiters_all_rows_joined (       select          dar.row_num baccstart_row_num       , lead(dar.row_num) on (order row_num) baccend_row_num       , dar.name       delimiters_all_rows dar     )     -- eliminate baccend rows have row_num values     select *     delimiters_all_rows_joined darj     name = 'baccstart'   )   loop      -- relevant rows data block     data_rows (       select d.*       data d         d.row_num > r_baccstart.baccstart_row_num , d.row_num < r_baccstart.baccend_row_num       , (         d.name in ('total','accname')         or (d.name = 'abcd' , d.row_num = (           select min(d2.row_num)           data d2           d2.row_num > r_baccstart.baccstart_row_num , d2.row_num < r_baccstart.baccend_row_num           , d2.name = 'abcd'         ))       )     )     -- agg rows single xml block (note: evalname dynamic xml element name)     select        xmlelement("baccstart"       , xmlagg(           xmlelement(evalname(dr.name), dr.value)           order decode(dr.name, 'total', 1, 'abcd', 2, 3)         )       ) xml_data     l_xml_data     data_rows dr;      insert data_xml values (l_xml_data);    end loop baccstart_loop;  end;  

i tried work in single query, xmlagg performance seems drop through floor apply group by many rows (something i've seen happen time , time again). performance became more acceptable when xmlagg limited few rows possible.

the resulting xml gets inserted table called data_xml (just see results), can substitute whatever need xml fragments once they're generated!

i'd advise if inserting data table, insert/select opposed select into followed insert it'll faster due lack of context switching between sql , pl/sql.

the following ddl/dml used set example:

create table data (   row_num integer , name    varchar2(10) , value   varchar2(10) ) /  create table data_xml (   xml_data xmltype ) /  create sequence data_seq start 1 increment 1 cache 1000 /  begin    idx in 1 .. 500 loop      insert data (row_num, name, value)      values (data_seq.nextval, 'docstart', null);      insert data (row_num, name, value)      values (data_seq.nextval, 'baccstart', null);      insert data (row_num, name, value)      values (data_seq.nextval, 'abcd', 'abcd');      insert data (row_num, name, value)      values (data_seq.nextval, 'abcd', 'abcd2');      insert data (row_num, name, value)      values (data_seq.nextval, 'pqrs', 'pqrs');      insert data (row_num, name, value)      values (data_seq.nextval, 'pqrs', 'pqrs2');      insert data (row_num, name, value)      values (data_seq.nextval, 'total', '100');      insert data (row_num, name, value)      values (data_seq.nextval, 'accname', 'name');      insert data (row_num, name, value)      values (data_seq.nextval, 'baccend', null);      insert data (row_num, name, value)      values (data_seq.nextval, 'baccstart', null);      insert data (row_num, name, value)      values (data_seq.nextval, 'abcd', 'abcd');      insert data (row_num, name, value)      values (data_seq.nextval, 'abcd', 'abcd2');      insert data (row_num, name, value)      values (data_seq.nextval, 'pqrs', 'pqrs3');      insert data (row_num, name, value)      values (data_seq.nextval, 'pqrs', 'pqrs4');      insert data (row_num, name, value)      values (data_seq.nextval, 'total', '150');      insert data (row_num, name, value)      values (data_seq.nextval, 'accname', 'name');      insert data (row_num, name, value)      values (data_seq.nextval, 'baccend', null);      insert data (row_num, name, value)      values (data_seq.nextval, 'docend', null);    end loop;  end; / 

Comments

Popular posts from this blog

Perl - how to grep a block of text from a file -

delphi - How to remove all the grips on a coolbar if I have several coolbands? -

javascript - Animating array of divs; only the final element is modified -