Sea*_* M. 1 sql oracle plsql character-encoding oracle-sqldeveloper
如果我有一个原始字符串并将其转换为varchar2然后将其转换为raw,则所有原始信息仍然存在.但是,如果我将它转换为varchar2然后将任何内容连接到它(包括一个空字符串),我会丢失最后一个字符.这是我用来复制它的代码:
SET SERVEROUTPUT ON;
DECLARE
raw_string RAW(100);
v_string VARCHAR2(100);
raw_string2 RAW(100);
BEGIN
raw_string := 'C5C6C7';
v_string := utl_raw.cast_to_varchar2(raw_string);
dbms_output.put_line('Raw string: ' || utl_raw.cast_to_raw(v_string) );
v_string := v_string || '';
dbms_output.put_line('New raw string: ' || utl_raw.cast_to_raw(v_string) );
END;
/
Run Code Online (Sandbox Code Playgroud)
第11行和第13行之间的唯一区别是第6行是在v_string与空字符串连接之后运行的.但输出是这样的:
Raw string: C5C6C7
New raw string: C5C6
Run Code Online (Sandbox Code Playgroud)
如果我不连接任何内容,新的原始字符串将是相同的,但如果我向字符串添加任何内容,即使在它的前面,它将丢失最后一部分.它只发生在某些字符上.如果我以'61'(小写'a')结束原始,那么什么都不会丢失.
我正在使用Oracle SQl Developer v.3.2.20.09
这一直困扰我一段时间,我不确定我是否遗漏了什么或者这只是一个错误,但任何帮助都会非常感激.
当你和打RAWs和VARCHARs,这是强制性的,你向我们提供您正在使用(数据库字符集和客户端CS)的字符集.
原因是每个字节值对于原始字节是合法的,从.0x00到0xFF.而大多数字符集都有非法值:字节值对应于无字符.
当Oracle遇到这样的值时,后果可能是不可预测的.这可能是这里发生的事情.
例如,在UTF-8中,二进制表示以'110 ...'开头的字节是双字节字符的第一个字节.
这正是你的情况:一个以a开头的字节C有一个以二进制表示开头的二进制表示,1100并且只能是一个双字节字符的第一个字节.第二个字节必须以10..(8到B)开头.因此,如果我不得不猜测我会预测你使用的是UTF-8,因为它具有许多非法字节值而众所周知.
我们可以观察到使用非法的UTF-8值会导致许多问题:
SQL> select utl_raw.cast_to_varchar2('C5C6') i0 from dual;
I0
--------------------------------------------------------------------------------
ÅÆ
SQL> select utl_raw.cast_to_varchar2('C5C6')||'' i1 from dual;
I1
--------------------------------------------------------------------------------
Å
SQL> select utl_raw.cast_to_varchar2('C5C6')||''||'' i2 from dual;
I2
--------------------------------------------------------------------------------
Run Code Online (Sandbox Code Playgroud)
事实上,对于任何字符集,盲目地将原始数据转换为varchar2通常是一个坏主意.当您知道这些值是合法的时(或者raw本身是来自varchar2的转换),您只想转换为varchar2.
当您需要使用varchar2表示raw时,为了显示或通过文本介质发送,使用它们hextoraw或编码(例如base64with UTL_ENCODE)更安全.
| 归档时间: |
|
| 查看次数: |
612 次 |
| 最近记录: |