I am trying to build some very large XML files via PL/SQL in Oracle 11g. I am trying to build the files iteratively - fetch one row, write to file, get next row, etc. Below is my code. I am having issues on where to define the CLOB.
I get two errors depending on where I initialize and free the CLOB: 1-Exceeding memory -- when initializing CLOB before loop and freetemporary after loop 2- Can't find the clob(invalid LOB locator specified) -- when initialize in loop and free in loop, or initialize out and free in loop
Please advise what the issue is in my approach or what the best approach is to build a large XML file iteratively.
PROCEDURE sql_to_xml(p_sql IN VARCHAR2,
p_fileName IN VARCHAR2,
p_dir IN VARCHAR2,
p_xml_created OUT VARCHAR2) IS
xml_result CLOB;
doc dbms_xmldom.DOMDocument;
ctx DBMS_XMLGEN.ctxHandle;
vv_exit_code varchar2(5);
vv_ctx_open varchar2(1) := 'N';
max_rows NUMBER := 5;
BEGIN
vv_exit_code := 'XML1';
ctx := dbms_xmlgen.newcontext(p_sql);
vv_ctx_open := 'Y';
DBMS_OUTPUT.put_line(vv_exit_code);
vv_exit_code := 'XML2';
DBMS_XMLGEN.SETCONVERTSPECIALCHARS (ctx,TRUE);
DBMS_OUTPUT.put_line(vv_exit_code);
DBMS_LOB.CREATETEMPORARY(xml_result,true);
while DBMS_XMLGEN.GETNUMROWSPROCESSED(ctx) < max_rows
LOOP
vv_exit_code := 'XML3';
xml_result := dbms_xmlgen.getXML(ctx);
DBMS_OUTPUT.put_line(vv_exit_code);
DBMS_output.put_line('Xml result is: ' ||dbms_lob.substr( xml_result, 4000, 1 ));
IF xml_result is not null THEN
vv_exit_code := 'XML4';
doc := dbms_xmldom.newDOMDocument(xml_result);
DBMS_OUTPUT.put_line(vv_exit_code);
vv_exit_code := 'XML5';
dbms_xmldom.writeToFile(doc,p_dir||'/'||p_fileName, 'ISO-8859-1');
DBMS_OUTPUT.put_line(vv_exit_code);
vv_exit_code := 'XML6';
dbms_xmldom.freeDocument(doc);
p_xml_created := 'TRUE';
DBMS_OUTPUT.put_line(vv_exit_code);
ELSE
p_xml_created := 'FALSE';
END IF;
DBMS_OUTPUT.PUT_LINE('XML Result: '||xml_result);
dbms_lob.FREETEMPORARY(xml_result);
end loop;
DBMS_XMLGEN.CLOSECONTEXT (ctx);
vv_ctx_open := 'N';
EXCEPTION
WHEN out_of_process_memory THEN
IF vv_ctx_open = 'Y' THEN
DBMS_XMLGEN.CLOSECONTEXT (ctx);
END IF;
gv_err_msg := substr(sqlerrm,1,2000);
DBMS_OUTPUT.put_line(gv_process_name||' failed '||gv_err_msg);
RAISE_APPLICATION_ERROR(-20906,gv_process_name||' failed'||gv_err_msg);
dbms_output.put_line('XML_EXPORT failed (out_of_process_memory exception) executing '||p_sql);
raise_application_error(-20906,'XML_EXPORT (out_of_process_memory exception) failed executing '||p_sql);
WHEN OTHERS THEN
IF vv_ctx_open = 'Y' THEN
DBMS_XMLGEN.CLOSECONTEXT (ctx);
END IF;
if xml_result is NULL then
gv_err_msg := substr(sqlerrm,1,2000);
DBMS_OUTPUT.put_line(gv_process_name||' failed '||gv_err_msg);
-- RAISE_APPLICATION_ERROR(-20906,gv_process_name||' failed'||gv_err_msg);
dbms_output.put_line('XML_EXPORT failed (xml results are NULL) executing '||p_sql);
raise_application_error(-20906,'XML_EXPORT (xml results are NULL) failed executing '||p_sql);
else
gv_err_msg := substr(sqlerrm,1,2000);
DBMS_OUTPUT.put_line(gv_process_name||' failed '||gv_err_msg);
dbms_output.put_line('XML_EXPORT failed (others exception) executing '||p_sql);
DBMS_OUTPUT.put_line('Export Directory is: '||p_dir||'/'||p_fileName);
raise_application_error(-20906,'XML_EXPORT (others exception) failed executing '||p_sql);
end if;
END sql_to_xml;