Skip to Main Content
  • Questions
  • xmlquery to update more than 2426 nodes in XML

Breadcrumb

Question and Answer

Chris Saxon

Thanks for the question, Nama.

Asked: February 28, 2017 - 9:39 am UTC

Last updated: March 01, 2017 - 2:36 pm UTC

Version: Oracle Database 11g Release 11.2.0.4.0 - 64bit Production

Viewed 1000+ times

You Asked

Hi,

I have a scenario to update more than 2500 nodes in an XML.

When i try to update more than 2426 nodes, I am getting an error as given below.

ORA-19112: error raised during evaluation:
XVM-00004: internal error "code buffer overflow".


The PLSQL block to update 2426 nodes is given in live SQL link.
https://livesql.oracle.com/apex/livesql/file/content_EM3I5LRDTVANV3XRO2GR7RAFM.html

The same PLSQL block gives the above error while trying to update for 2427 ( or more) nodes.

Is this the maximum limit XQUERY in oracle SQL will support?

Thanks in Advance.


with LiveSQL Test Case:

and Chris said...

This does appear to be a limitation, though I can't find this documented anywhere...

But this relates the to number of nodes you list in the modify expression. Not the nodes in the document!

So I have to ask:

Why are you explicitly listing out all the nodes in your XQuery expression? You can use wildcards to match nodes. So in your example you can replace the whole looping nonsense building v_clob_upd_sql with:

declare default element namespace "http://www.mywrb.com/test/mys";  (: :)  
  copy $tmp := $inxml modify (
    (for $i in $tmp/datapacket/data/sec/row/* return replace value of node $i with xs:integer($i + 1))
  ) 
  return $tmp


This enables you to update documents with far more than 2426 nodes:

DECLARE 
  v_data_xml CLOB; 
  v_clob_upd_sql VARCHAR2(1000); 
  v_bool BOOLEAN := false; 
  LV_OUT_XML XMLTYPE; 
  lv_number_of_nodes number := 10000; 
BEGIN 
 
 -- Variable holding the data XML  
  v_data_xml := q'[<?xml version="1.0" encoding="UTF-8"?>    
                  <mys:datapacket                    
                  xmlns:html="http://www.w3.org/1999/xhtml"                    
                  xmlns:mys="http://www.mywrb.com/test/mys">      
                  <mys:data>     
                  <mys:sec>     
                  ]'; 
  FOR I IN 1..lv_number_of_nodes 
  LOOP 
    dbms_lob.append(v_data_xml,'<mys:row><mys:pk'||i||'>'||i||'</mys:pk'||i||'></mys:row>'); 
  END LOOP; 
  DBMS_LOb.APPEND(v_data_xml,'</mys:sec></mys:data></mys:datapacket>'); 
   
  -- XMLQUERY to update all the nodes in the data XML  
  v_clob_upd_sql := 'declare default element namespace "http://www.mywrb.com/test/mys";  (: :)  
  copy $tmp := $inxml modify (
    (for $i in $tmp/datapacket/data/sec/row/* return replace value of node $i with xs:integer($i + 1))
  ) 
  return $tmp';
   
  SELECT 
    xmlquery( v_clob_upd_sql passing xmltype(v_data_xml) AS "inxml" returning content) 
  INTO lv_out_xml 
  FROM dual; 
  dbms_output.put_line(substr(lv_out_xml.getClobVal(), 1, 400));
END;
/

<?xml version="1.0" encoding="UTF-8"?>
<mys:datapacket xmlns:mys="http://www.mywrb.com/test/mys" xmlns:html="http://www.w3.org/1999/xhtml">
  <mys:data>
    <mys:sec>
      <mys:row>
        <mys:pk1>2</mys:pk1>
      </mys:row>
      <mys:row>
        <mys:pk2>3</mys:pk2>
      </mys:row>
      <mys:row>
        <mys:pk3>4</mys:pk3>
      </mys:row>
      <mys:row>
        <mys:pk4>5</mys:pk4>
      </mys:row>
      <mys:row>
        <mys:pk5>6</mys:pk5>
      </mys:row>
      <mys:row>
        <mys:pk6>7</mys:pk6>
      </mys:row>
      <mys:ro

Rating

  (2 ratings)

Is this answer out of date? If it is, please let us know via a Comment

Comments

How to implement with out using wildcards

Nama K, February 28, 2017 - 11:54 am UTC

I gave sample XML document having 2500 nodes, the real time XML may not have the similar name format, hence I cannot use wildcards to match. Is not there any other option other than using wildcards?
Chris Saxon
February 28, 2017 - 2:43 pm UTC

Surely there's some rule you can follow so you don't have to explicitly list each node separately? You can use XPath expressions to identify particular nodes.

If you really can't, then you could always run the XMLQuery multiple times. Once for the first 2,500 nodes, then for the next 2,500 and so on.

Nama K, March 01, 2017 - 5:05 am UTC

Thanks for your inputs.

I will try to use the XPATH expression if possible, otherwise will update in batches of 2500 nodes.

Would be great If you can able to point the link from oracle documentation about the maximum (length or nodes) for consolidated XML update operation.
Chris Saxon
March 01, 2017 - 2:36 pm UTC

This limitation isn't documented as far as I know. If this is causing you major issues, you could take this up with support.

More to Explore

CLOB/BLOB/etc

Complete documentation on Securefiles and Large Objects here