带有不适当字符集的 Clob
Clob with inappropriate charset
我想将文件加载到 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;
/
我创建了一个包含 'test file' 的平面文件 'sample.txt',当我最终打印它时,我得到了“瑥獴楬攊”。我在数据库中使用的字符集是 utf-8。为什么我的编码搞砸了?
我找到了一些在线编码器 https://www.urlencoder.org/。
当我将中文字母放入其中并使用 UTF16-BE 作为目标字符集时,我得到了 'test%20file%0A'。但是我还是不知道为什么我的编码搞砸了。
您确定您的数据库字符集是 AL32UTF8 并且磁盘上的文件是 ASCII 吗?因为它看起来像东西,所以某处是 AL16UTF16(我认为它与 UTF-16BE 相同)。
您的测试字符串 "test file\n" 编码为 UTF8 字节 0x746573742066696C650A。你实际上有 5 个亚洲字符,因为第三个是不可打印的字符,LEFT-TO-RIGHT ISOLATE。
当我将 "test file\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
我想将文件加载到 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;
/
我创建了一个包含 'test file' 的平面文件 'sample.txt',当我最终打印它时,我得到了“瑥獴楬攊”。我在数据库中使用的字符集是 utf-8。为什么我的编码搞砸了?
我找到了一些在线编码器 https://www.urlencoder.org/。 当我将中文字母放入其中并使用 UTF16-BE 作为目标字符集时,我得到了 'test%20file%0A'。但是我还是不知道为什么我的编码搞砸了。
您确定您的数据库字符集是 AL32UTF8 并且磁盘上的文件是 ASCII 吗?因为它看起来像东西,所以某处是 AL16UTF16(我认为它与 UTF-16BE 相同)。
您的测试字符串 "test file\n" 编码为 UTF8 字节 0x746573742066696C650A。你实际上有 5 个亚洲字符,因为第三个是不可打印的字符,LEFT-TO-RIGHT ISOLATE。
当我将 "test file\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