我一直在努力将包含汉字并以UTF-8编码的XML文件从外部各方导入到我们的使用US7ASCII编码的Oracle数据库中。但是,下面的错误一直提示:
pkg_dxe.get_xmldata: ORA-31011: XML parsing failed
ORA-19202: Error occurred in XML processing
LPX-00200: could not convert from encoding UTF-8 to US-ASCII
Error at line 1
处理导入过程的PL \ SQL代码:
v_xml := XMLType(bfilename('XMLDIR_IBISAPP', 'xmldata.xml'), nls_charset_id('UTF8'));
Select count(*) into v_cnt from XML_TAB_A;
If v_cnt > 0 then
update XML_TAB_A set
xml_data = v_xml,
timestamp = sysdate;
else
Insert into XML_TAB_A(xml_data, timestamp) values (v_xml, sysdate);
end if;
XML示例:
<?xml version="1.0" standalone="yes" ?>
<APPLICATION>
<DXE_APPLICATION>
<APP_TRAN_NO>20180621031622817</APP_TRAN_NO>
</DXE_APPLICATION>
<DXE_CUSTOMER>
<APP_TRAN_NO>20180621031622817</APP_TRAN_NO>
<SEQ>0</SEQ>
<CUST_TITLE>Mr.</CUST_TITLE>
<CUST_NAME>HELLO</CUST_NAME>
<CUST_GNAME>HELLO</CUST_GNAME>
<CUST_ONAME>hello</CUST_ONAME>
<CUST_NAME_CHN>陳大文</CUST_NAME_CHN>
</DXE_CUSTOMER>
</APPLICATION>
导致该错误的字段是Cust_Name_Chn,但是我们不能排除在其他字段中还会提供汉字的情况。
有什么方法可以正确地将XML导入我们的Oracle数据库,而不会在包含中文字符时提示错误?如果在此阶段导入后无法读取汉字,则可以接受。
我尝试使用CONVERT()函数,但错误LPX-00200仍然存在。
答案 0 :(得分:0)
没有US7ASCII数据库可供测试,但是您可以通过getblobval方法将xmltypes字符集转换为
with x as
(select xmltype('<?xml version="1.0" standalone="yes" ?>
<APPLICATION>
<DXE_APPLICATION>
<APP_TRAN_NO>20180621031622817</APP_TRAN_NO>
</DXE_APPLICATION>
<DXE_CUSTOMER>
<APP_TRAN_NO>20180621031622817</APP_TRAN_NO>
<SEQ>0</SEQ>
<CUST_TITLE>Mr.</CUST_TITLE>
<CUST_NAME>HELLO</CUST_NAME>
<CUST_GNAME>HELLO</CUST_GNAME>
<CUST_ONAME>hello</CUST_ONAME>
<CUST_NAME_CHN>陳大文</CUST_NAME_CHN>
</DXE_CUSTOMER>
</APPLICATION>') a from dual)
select xmltype(x.a.getblobval(NLS_CHARSET_ID('US7ASCII')),NLS_CHARSET_ID('US7ASCII')) y
from x x;
将名称行转到:
<CUST_NAME_CHN>陳大文</CUST_NAME_CHN>
答案 1 :(得分:0)
您应该考虑将数据库迁移到UTF-8,请参见Character Set Migration。将数据库从US7ASCII
迁移到AL32UTF8
不会造成任何麻烦。
不支持NCHAR,NVARCHAR2和NCLOB –不支持Oracle XML DB 支持将SQL数据类型NCHAR,NVARCHAR2和NCLOB用于任何 以下:
在XML模式中使用SQLType注释将XML元素或属性映射到这些数据类型
使用SQL / XML函数XMLElement,XMLAttributes和XMLForest从这些数据类型生成XML数据
在SQL / XML函数XMLQuery和XMLTable中,在表上使用XQuery函数ora:view(不建议使用),fn:doc和fn:collection 包含具有这些数据类型的列
处理,存储或生成包含多字节的XML数据 字符,Oracle强烈建议您使用AL32UTF8作为 数据库字符集。
您可以将纯数据存储为NCLOB
:
CREATE TABLE XML_TAB_A (xml_data NCLOB, ts TIMESTAMP);
DECLARE
v_nclob NCLOB;
v_cnt NUMBER;
xbfile BFILE;
destOffset INTEGER := 1;
srcOffset INTEGER := 1;
langContext INTEGER := DBMS_LOB.DEFAULT_LANG_CTX;
warning INTEGER;
BEGIN
xbfile := BFILENAME ('XMLDIR_IBISAPP', 'xmldata.xml');
DBMS_LOB.OPEN (xbfile);
DBMS_LOB.CREATETEMPORARY (v_nclob, TRUE, DBMS_LOB.SESSION);
DBMS_LOB.LOADCLOBFROMFILE (
dest_lob => v_nclob,
src_bfile => xbfile,
amount => DBMS_LOB.GETLENGTH(xbfile),
dest_offset => destOffset,
src_offset => srcOffset,
bfile_csid => NLS_CHARSET_ID('AL32UTF8'),
lang_context => langContext,
warning => warning);
DBMS_LOB.CLOSE (xbfile);
SELECT COUNT(*) INTO v_cnt FROM XML_TAB_A;
IF v_cnt > 0 THEN
UPDATE XML_TAB_A SET
xml_data = v_nclob,
ts = SYSDATE;
ELSE
INSERT INTO XML_TAB_A(xml_data, ts) VALUES (v_nclob, SYSDATE);
END IF;
END;
但是,您将无法使用任何XMLTYPE函数。
答案 2 :(得分:0)
我找到了一种将XML文件读入Clob,然后将其转换回XMLType以避免提示编码错误的解决方案
file := bfilename('XMLDIR_IBISAPP', 'xmldata.xml');
dbms_lob.createTemporary(contents, true, dbms_lob.session);
dbms_lob.fileopen(file, dbms_lob.file_readonly);
dbms_lob.loadClobfromFile(contents, file, dbms_lob.getLength(file), dest_offset, src_offset, nls_charset_id('AL32UTF8'), lang_context, conv_warning);
dbms_lob.fileclose(file);
v_xml := XMLTYPE.createXML(contents);
Update xml_tab_a set
xml_data = v_xml,
timestamp = sysdate;