Oracle神秘的Unicode代码点

时间:2015-02-26 10:49:45

标签: oracle unicode utf-8 oracle11g

在应该包含有效XML1.0 xml的CLOB列上调用XMLTYPE()时(db编码应该是UTF-8),会出现以下错误消息(我来自意大利):

ORA-31011: Analisi XML non riuscita
ORA-19202: Errore durante l'elaborazione XML
LPX-00217: carattere non valido 15577023 (U+EDAFBF)
Error at line 240
ORA-06512: a "SYS.XMLTYPE", line 272
ORA-06512: a line 1
31011. 00000 -  "XML parsing failed"
*Cause:    XML parser returned an error while trying to parse the document.
*Action:   Check if the document to be parsed is valid.

现在这个无效字符以 Unicode codepoint EDAFBF 的形式给出。问题是根据Unicode规范(维基百科),除 10FFFF 之外没有代码点。那么这个错误意味着什么?

使用SQLDeveloper检查此CLOB(并将其复制到Notepad ++,编码设置为utf-8)并不会发现除了一些奇怪的字符之外的任何异常,这些字符显然来自用户浏览器,当他从Microsoft Word文档复制文本时(但是CLOB,至少从SQLDeveloper UI复制并由带有UTF-8编码的Notepad ++展示,似乎是一个有效的UTF-8文本。)

有没有办法重现直接填充Oracle的错误(从SQLDeveloper或以其他方式)? (联系最终用户以了解他在网络表单中的确切内容是有问题的)

1 个答案:

答案 0 :(得分:3)

不解决问题的第一部分,但您可以使用RAW值重现它:

select xmltype('<dummy>'
  || utl_raw.cast_to_varchar2(cast('EDAFBF' as raw(6)))
  || '</dummy>')
from dual;

Error report -
SQL Error: ORA-31011: XML parsing failed
ORA-19202: Error occurred in XML processing
LPX-00217: invalid character 15577023 (U+EDAFBF)
Error at line 1
ORA-06512: at "SYS.XMLTYPE", line 310
ORA-06512: at line 1

只选择角色:

select utl_raw.cast_to_varchar2(cast('EDAFBF' as raw(6)))
from dual;

...显示为一个小方块,里面有一个更小的问号(我认为)在SQL Developer中对我来说(版本4.1),但这只是它如何选择渲染那;复制和粘贴仍然会给the replacement character�,因为代码点就像你说的那样无效。 XMLType的有效性比CLOB更严格。 unistr()函数也没有处理这个值,这并不是一件令人意外的事。

(您不需要将字符串转换为raw(6),只有utl_raw.cast_to_varchar2('EDAFBF')具有相同的效果;但是明确地执行该操作会使得它更清楚地发生了什么,我想)。

我不知道如果没有某种损坏,这可能会进入你的文件,可能是通过我认为的拙劣的字符集转换。您可以使用dbms_lob.replace_fragment()或类似的替换或移除该角色,但当然可能还有其他您尚未击中的角色,并且充其量您只能治疗症状而不是原因。