从oracle存储过程导出XML文件中的所有扩展ASCII代码(字符代码128-255)

时间:2014-05-01 08:29:08

标签: sql xml oracle xml-parsing plsqldeveloper

我创建了一个Store Procedure来生成Table Data的xml文件, 但在我的数据库中,某些表格有"extended ASCII codes (character code 128-255)"

当我生成xml文件时,它会显示错误"ORA-31061: XDB error: special char to escaped char conversion failed."

所以我将这些字符替换为空格,但我需要XML文件中的所有ASCII代码(字符代码128-255)。

请帮忙

我的商店程序如下:

create or replace
PROCEDURE Export_project6
(
   V_TABLE_NAME1 IN varchar2,
   v_FLAG OUT NUMBER
  )
AS
BEGIN
         ----- Export  table data
     DECLARE
        v_file  UTL_FILE.file_type;
        qryCtx DBMS_XMLGEN.ctxHandle;
        result CLOB;
        v_FILENAME varchar2(50);
        V_TABLE_NAME varchar2(50);
        xt_data xmltype;
        v_ctx dbms_xmlgen.ctxHandle;
        rc_data sys_refcursor;



      BEGIN
         V_TABLE_NAME := UPPER(V_TABLE_NAME1) ;      
         v_file := UTL_FILE.fopen('MYXML',V_TABLE_NAME||'.xml', 'W');
            OPEN rc_data FOR
                 'select * FROM '||V_TABLE_NAME||' ORDER BY 1' ;
                  v_ctx := dbms_xmlgen.newContext (rc_data);
                  DBMS_XMLGEN.USEITEMTAGSFORCOLL (v_ctx);
                  DBMS_XMLGEN.SETNULLHANDLING(v_ctx, 1);
                  DBMS_XMLGEN.setrowsettag(v_ctx,'root');
                  DBMS_XMLGEN.setrowtag(v_ctx,V_TABLE_NAME );
          result:=  DBMS_XMLGEN.getXML(v_ctx);
          result := REPLACE( result, '<?xml version="1.0"?>','<?xml version="1.0" encoding="UTF-8" standalone ="yes"?>');
          -- DBMS_XMLGEN.RESTARTQUERY (v_ctx);  
          -- xt_data := dbms_xmlgen.getXMLType (v_ctx);

          dbms_xslprocessor.clob2file( result, 'MYXML', ''||V_TABLE_NAME||'.xml',1);
          dbms_xmlgen.closeContext (v_ctx);
          v_FLAG := 1;

      EXCEPTION
      WHEN OTHERS THEN
          DBMS_OUTPUT.PUT_LINE(SQLERRM);
          DBMS_XMLGEN.closeContext (v_ctx);
          v_FLAG := 0;
      END ;

请在这里提供建议和帮助

END Export_project6;

1 个答案:

答案 0 :(得分:0)

至少部分问题是你指定的文件应该是US7ASCII,它只允许前128个ASCII字符,而不是128-255的扩展值。你正在这一行:

dbms_xslprocessor.clob2file( result, 'MYXML', ''||V_TABLE_NAME||'.xml',1);

您将1作为the fourth parameter, csid传递。该值代表US7ASCII:

SQL> select nls_charset_name(1) from dual;

NLS_CHAR
--------
US7ASCII

您的XML是UTF-8,但使用encoding="UTF-8"指定XML与文件的编写方式无关。任何无法识别的字符都会替换为?。因此,您可能希望对文件使用相同的设置:

SQL> select nls_charset_id('UTF8') from dual;

NLS_CHARSET_ID('UTF8')
----------------------
                   871

所以:

dbms_xslprocessor.clob2file( result, 'MYXML', ''||V_TABLE_NAME||'.xml',871);

或更清楚:

dbms_xslprocessor.clob2file( result, 'MYXML', ''||V_TABLE_NAME||'.xml',
  nls_charset_id('UTF8'));

但是将其保留为默认值可能没问题 - 完全没有指定csid,或者明确地将其设置为零 - 具体取决于我们的数据库环境。

如果你“替换所有ASCIICHAR(0-30)like:11♀:12♫:14☼:15►:16◄:17↕:18!:19¶:20你提到你避免ORA-31061错误”。这些符号不是您对ASCII的期望,因此您的角色集或客户端或其他东西似乎以不同的方式解释它们。

我得到了所有ASCII control characters,0到31的错误,但可打印的除外:9,10或13.但这就是预期的,该范围内的其他字符are not valid in XML 1.0:< / p>

  
      
  • U + 0009,U + 000A,U + 000D:这些是XML 1.0中唯一接受的C0控件;
  •   

同一页面显示XML 1.1中允许使用更多但仍然不是全部的控制字符,但据我所知Oracle only supports 1.0。如果您确实在数据中有控制字符,则需要剥离它们(保留标签,换行和回车);其余的在最终的XML中无意义,并且可能在现有数据中使用有限。我不确定这是否是真实数据,或者您是否将这些值生成为测试。