使用UTF8作为字符集将blob数据转换为clob数据时, 似乎Oracle(11gR2)将字节0xE2 0x80 0x82转换为0x20。 正如我怀疑的那样,这是完全错的吗?甚至可能是一个错误?
我需要编辑包含UTF8编码数据的clob,同时保留原始字符(所有字符,尤其是EN空格)。
仅供参考:0xE2 0x80 0x82是“EN空间”,而0x20是“正常空间”
http://docs.oracle.com/cd/B19306_01/appdev.102/b14258/d_lob.htm#i1020356
http://en.wikipedia.org/wiki/Space_%28punctuation%29
http://www.utf8-chartable.de/unicode-utf8-table.pl?start=8192
declare
v_clob clob;
v_clob_content varchar2(8);
v_content_ok varchar2(64);
v_content_bad varchar2(64);
v_blob blob;
v_raw raw(8);
v_c_dst_offset pls_integer := 1;
v_c_src_offset pls_integer := 1;
v_c_ctx pls_integer := 0;
v_c_warn pls_integer;
begin
-- Create temporary lobs and cache them
dbms_lob.createtemporary(v_blob,true);
dbms_lob.createtemporary(v_clob,true);
-- Write 0xE2 0x80 0x82 to the BLOB
v_raw := hextoraw('E2') || hextoraw('80') || hextoraw('82');
dbms_lob.write(v_blob,utl_raw.length(v_raw),1,v_raw);
-- Convert the BLOB to CLOB using AL32UTF8 as encoding
dbms_lob.converttoclob(
v_clob,
v_blob,
dbms_lob.getlength(v_blob),
v_c_dst_offset,
v_c_src_offset,
nls_charset_id('AL32UTF8'),
v_c_ctx,
v_c_warn);
-- Put the CLOB contents into a varchar2
v_clob_content := dbms_lob.substr(v_clob,dbms_lob.getlength(v_clob));
-- Output the HEX value of respectively the BLOB content and the CLOB content
select rawtohex(v_clob_content) into v_content_bad from dual;
select rawtohex(v_raw) into v_content_ok from dual;
dbms_output.put_line('[' || v_content_bad || ']');
dbms_output.put_line('[' || v_content_ok || ']');
-- Release resources
dbms_lob.freetemporary(v_clob);
dbms_lob.freetemporary(v_blob);
end;
/
输出:
[20]
[E28082]
PL/SQL procedure successfully completed.
答案 0 :(得分:3)
你的数据库可能没有在AL32UTF8
字符集下运行?
即:
SQL> col value format a20
SQL> select * from nls_database_parameters where parameter like '%CHARACTERSET%';
PARAMETER VALUE
------------------------------ --------------------
NLS_CHARACTERSET AL32UTF8
NLS_NCHAR_CHARACTERSET UTF8
SQL> declare
2 v_clob clob;
3 v_clob_content varchar2(8);
4 v_content_ok varchar2(64);
5 v_content_bad varchar2(64);
6 v_blob blob;
7 v_raw raw(8);
8
9 v_c_dst_offset pls_integer := 1;
10 v_c_src_offset pls_integer := 1;
11 v_c_ctx pls_integer := 0;
12 v_c_warn pls_integer;
...
46 end;
47 /
[E28082]
[E28082]
PL/SQL procedure successfully completed.
vs在非al32utf8数据库中运行:
SQL> select * from nls_database_parameters where parameter like '%CHARACTERSET%';
PARAMETER VALUE
------------------------------ --------------------
NLS_NCHAR_CHARACTERSET UTF8
NLS_CHARACTERSET WE8ISO8859P15
SQL> set serverout on
SQL> declare
2 v_clob clob;
...
47 /
[BF]
[E28082]
在我的西方ISO数据库中转换了吊球。如果需要将AL32UTF8
保留在非二进制数据类型中,请确保在该字符集下运行数据库。