从oracle表生成xml文件 [英] generate xml file from oracle table

查看:155
本文介绍了从oracle表生成xml文件的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

当我在存储过程下运行时,它显示错误.这里有一些特殊的字符相关问题,所以我不能生成xml文件,这里的xml格式与

when I ran below store procedure then it shows error. here some special char related issue ,so i cant generate xml file , here xml format same as generate XML from oracle tables

Connecting to the database DB_old.
ORA-29285: file write error
ORA-06512: at "SYS.UTL_FILE", line 148
ORA-06512: at "SYS.UTL_FILE", line 889
ORA-06512: at "DBO_17FEB.EXPOR1", line 60
ORA-06512: at line 6
Process exited.
Disconnecting from the database DB_old.



-------------------



create or replace 
PROCEDURE Expor1 
(
   V_TABLE_NAME IN varchar2
  )
AS
BEGIN
         ----- Export  table data
      DECLARE
        v_file  UTL_FILE.file_type;
        qryCtx DBMS_XMLGEN.ctxHandle;
        result CLOB;
        result1 CLOB;
        v_FILENAME varchar2(30);
      BEGIN

       IF UPPER(V_TABLE_NAME) = 'PROJECT' THEN
      qryCtx :=  dbms_xmlgen.newContext ('SELECT * from '||V_TABLE_NAME ||'' );

       ELSIF UPPER(V_TABLE_NAME) = 'LOGFILE' THEN

      qryCtx :=  dbms_xmlgen.newContext ('select LOG_ID, USER_ID,RUN_DATE,PROCESS,MPOID,MODE_,trim(STATUS) as STATUS,
                                                 trim(regexp_replace(unistr(NOTES), ''[[:punct:]] '','''')) as NOTES, 
                                                 MARKDELETED from logfile where rownum<100 ' );

       ELSE
       qryCtx :=  dbms_xmlgen.newContext ('SELECT * from '||V_TABLE_NAME ||'' );
      END IF;


      v_FILENAME :=V_TABLE_NAME;
      DBMS_XMLGEN.setMaxRows(qryCtx, 5);
         v_file := UTL_FILE.fopen('MYXML', v_FILENAME || '.xml', 'W');
       UTL_FILE.put_line(v_file, '<XML><'||v_FILENAME||'></'||v_FILENAME||'> <RECORDS>');
       -- v_file := UTL_FILE.FOPEN('MYXML', v_FILENAME|| '.xml', 'R');

       LOOP
         DBMS_XMLGEN.SETNULLHANDLING(qryCtx ,null);
         DBMS_XMLGEN.setRowSetTag(qryCtx, 0);
         DBMS_XMLGEN.setRowTag(qryCtx, 'RECORD');

      -- save the XML into the CLOB field
       result :=  DBMS_XMLGEN.getXML(qryCtx);
       --result := REPLACE( result, '<?xml version="1.0"?>','<XML><'||v_FILENAME||'>'||result1 ||'</'||v_FILENAME||'>' );
         result := REPLACE( result, '<?xml version="1.0"?>',' ');
         result := REPLACE( result, '<_x0030_>',' ');
         result := REPLACE( result, '</_x0030_>',' '); 
         --result :=trim(result);
      -- UTL_FILE.put_line(v_file, '');
       EXIT WHEN DBMS_XMLGEN.getNumRowsProcessed(qryCtx) = 0; 
          -- store the XML to a XML files
       UTL_FILE.put_line(v_file, result);
      --UTL_FILE.put_line(v_file, '</XML>');
       END LOOP; 
      UTL_FILE.put_line(v_file, '</RECORDS></XML>');
       UTL_FILE.FCLOSE(v_file);

       END; 


END Expor1;

i am not able to handle some special char like : & / ; :/ . etc please help

推荐答案

ORA-29285: file write error与您之前提到的ORA-31061: XDB error: special char to escaped char conversion failed不是同一字符转换错误.确实不清楚您要得到哪个错误.如果是文件1,则字符转换不相关.

The ORA-29285: file write error isn't the same character-conversion error you referred to before, which was ORA-31061: XDB error: special char to escaped char conversion failed. It really isn't clear which error you're getting; if it's the file one then the character conversion isn't relevant.

当我在表上运行您的代码版本时,对于较小的表它可以正常工作,并且如果result大于32k个字符,则得到ORA-06502: PL/SQL: numeric or value error;或ORA-29285(如果大于32k则没有换行符).您已经丢失了clob上的循环,无法将其分块写入文件中.要像以前一样输出更大的值:

When I run your version of my code against my table, it works OK for smaller tables, and gets ORA-06502: PL/SQL: numeric or value error if result is more than 32k characters; or ORA-29285 if there is more than 32k without a line break. You've lost the looping over the clob to write it to the file in chunks. To output larger values, as I did before:

position pls_integer := 1;
chars pls_integer := 32767;
...
while position < dbms_lob.getlength(result) loop
  utl_file.put(v_file, dbms_lob.substr(result, chars, position));
  utl_file.fflush(v_file);
  position := position + chars;
end loop;

不确定在该过程中为什么会有内部块(declare/begin/`end').

Not sure why you have an inner block (declare/begin/`end') within the procedure.

如果您正在获取ORA-31061,那么我仍然不清楚是什么数据导致了您的问题,但是假设您正在执行的NOTES转换可以解决该问题,并且当您看到NOTES转换时,仍然会看到ORA-31061为您的LOGFILE表调用它,那可能是因为您重置了qryCtx.

If you are getting the ORA-31061 then I'm still unclear which data is causing you a problem, but assuming that the NOTES transformation you're doing solves that and you're still seeing ORA-31061 when you call this for your LOGFILE table, then that's probably because you reset qryCtx.

您将在提供的代码的第23行创建该代码:

You're creating that at line 23 in the code you provided as:

      qryCtx :=  dbms_xmlgen.newContext ('select LOG_ID, 
        USER_ID,RUN_DATE,PROCESS,MPOID,MODE_,STATUS,
        regexp_replace(unistr(NOTES), ''[[:punct:]]'','''') as NOTES,
        MARKDELETED from logfile' );

...,但随后在if/elsif/else块中执行此操作之后,然后在第39行使用以下命令覆盖它:

... but then after the if/elsif/else block where you do that, you then overwrite it at line 39 with:

      qryCtx :=  dbms_xmlgen.newContext ('SELECT * from '||V_TABLE_NAME ||'' );

因此,当您随后调用getXML(qryCtx)时,并不会获得NOTES的修改后的值.

So when you then call getXML(qryCtx) you aren't getting the modified values for NOTES.

这篇关于从oracle表生成xml文件的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆