带有不正确字符集的Clob

时间:2019-02-19 19:13:00

标签: oracle file character-encoding clob

我想将文件加载到plsql clob变量中,然后对其执行一些正则表达式转换。我的问题是我弄乱了我的字符集。

到目前为止,我已经尝试过:

declare 
 l_filename varchar2(100) := 'sample.txt';
 l_clob clob;
 l_bfile bfile;
 begin
 dbms_lob.createtemporary(l_clob, true);
 l_bfile := bfilename( 'SAMPLE_DIR', l_filename );
 dbms_lob.fileopen( l_bfile );
 dbms_lob.loadfromfile( l_clob, l_bfile, dbms_lob.getlength( l_bfile ));
 dbms_lob.fileclose( l_bfile );
 dbms_output.put_line(l_clob);
 end;
/

我创建了一个带有“测试文件”的平面文件“ sample.txt”,当我最终打印该文件时,我得到了“瑥獴⁦楬攊”。我在数据库中使用的字符集是utf-8。为什么我的编码搞乱了?

我找到了一些在线编码器https://www.urlencoder.org/。 当我将中文字母放入其中并使用UTF16-BE作为目标字符集时,得到了“ test%20file%0A”。但是我仍然不知道为什么我的编码搞砸了。

1 个答案:

答案 0 :(得分:2)

确定您的数据库字符集为AL32UTF8,并且磁盘上的文件为ASCII吗?因为看起来像什么,所以某个地方是AL16UTF16(我认为它与UTF-16BE相同)。

您的测试字符串“ test file \ n”编码为UTF8字节0x746573742066696C650A。您实际上有 5 个亚洲字符,因为第三个是不可打印的字符,LEFT-TO-RIGHT ISOLATE。

将“测试文件\ n”转换为UTF16时,得到以下信息:

select dump( utl_i18n.raw_to_char( hextoraw('746573742066696C650A'), 'AL16UTF16' ), 1016 ) 
from dual;

Typ=1 Len=15 CharacterSet=AL32UTF8: e7,91,a5,e7,8d,b4,e2,81,a6,e6,a5,ac,e6,94,8a

select dump( '瑥獴⁦楬攊', 1016) from dual;

Typ=96 Len=15 CharacterSet=AL32UTF8: e7,91,a5,e7,8d,b4,e2,81,a6,e6,a5,ac,e6,94,8a

请注意,字节序列是相同的。第二个dump()具有Typ=96值,即NCHAR。您为数据库获得的字符集与我的相同吗?

select * from nls_database_parameters 
where parameter IN ('NLS_CHARACTERSET', 'NLS_NCHAR_CHARACTERSET' );

PARAMETER               VALUE
NLS_CHARACTERSET        AL32UTF8
NLS_NCHAR_CHARACTERSET  AL16UTF16