我创建了一个存储过程来生成一个表数据的xml文件,但在我的数据库中,有些表具有CCD_ 1。
当我生成xml文件时,它显示错误"ORA-31061: XDB error: special char to escaped char conversion failed."
因此,我将这些Char替换为空格,但我需要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;
问题的一部分是您指定的文件应该是US7ASICI,它只允许前128个ASCII字符,而不允许128-255的扩展值。你在这一行这样做:
dbms_xslprocessor.clob2file( result, 'MYXML', ''||V_TABLE_NAME||'.xml',1);
您将传递1
作为第四个参数csid
。该值表示US7ASICI:
SQL> select nls_charset_name(1) from dual;
NLS_CHAR
--------
US7ASCII
您的XML是UTF-8,但使用encoding="UTF-8"
指定它与文件的编写方式无关。任何未识别的字符都将替换为?
。因此,您可能希望对文件使用相同的设置:
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(,如♂ :11♀ :12♫ :14☼ :15► :16◄ :17↕ :18‼:19¶:20"。这些符号不是你对ASCII的期望,所以你的字符集或客户端或其他东西似乎对它们有不同的解释。
我得到了所有ASCII控制字符的错误,从0到31,除了可打印的字符:9、10或13。但这正是预期的,该范围内的其他字符在XML1.0:中无效
- U+0009、U+000A、U+000D:这些是XML 1.0中唯一接受的C0控件
同一页显示,XML1.1中允许使用更多(但不是全部(控制字符,但据我所知,Oracle只支持1.0。如果你的数据中确实有控制字符,你需要去掉它们(保留制表符、换行符和回车符(;剩下的内容在最终的XML中毫无意义,而且在现有数据中的使用可能有限。我不确定这是否是真实的数据,或者你是否生成了这些值作为测试。