【问题标题】:String loses last character when concatenated with empty string in Oracle SQL Developer在 Oracle SQL Developer 中与空字符串连接时,字符串会丢失最后一个字符
【发布时间】:2013-09-06 18:55:57
【问题描述】:

如果我有一个原始字符串并将其转换为 varchar2,然后将其转换回原始字符串,则所有原始信息仍然存在。但是,如果我将它转换为 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; 
/

第 11 行和第 13 行之间的唯一区别是第 13 行在 v_string 与空字符串连接之后运行。但是输出是这样的:

Raw string:     C5C6C7
New raw string: C5C6

如果我不连接任何东西,新的原始字符串将是相同的,但如果我在字符串中添加任何东西,即使在它的前面,它也会丢失最后一部分。它只发生在某些字符上。如果我以“61”(小写“a”)结束原始数据,则不会丢失任何内容。

我正在使用 Oracle SQl Developer v.3.2.20.09

这让我困惑了一段时间,我不确定我是否遗漏了什么或者这只是一个错误,但任何帮助将不胜感激。

【问题讨论】:

  • 我在 Toad - Oracle 11g 中运行了您的脚本,但没有得到相同的结果。 Raw string: C5C6C7 New raw string: C5C6C7 PL/SQL procedure successfully completed.

标签: sql oracle character-encoding plsql oracle-sqldeveloper


【解决方案1】:

当您使用RAWsVARCHARs 时,您必须向我们提供您正在使用的字符集(数据库字符集和客户端cs)。

原因是每个字节值对于原始字节都是合法的,从0x000xFF。而大多数字符集都有非法值:不对应任何字符的字节值。

当 Oracle 遇到此类值时,后果可能无法预料。这可能就是这里发生的事情。

例如在 UTF-8 中,byte whose binary representation starts with '110...' is the first byte of a two-byte character

这正是您的情况:以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
--------------------------------------------------------------------------------

事实上,对于任何字符集,将 raw 盲目地转换为 varchar2 通常是个坏主意。 当您知道这些值是合法的时,您只想转换为 varchar2(即 raw 本身就是从 varchar2 转换而来的)。

当您需要用 varchar2 表示原始数据以显示或通过文本媒体发送时,使用hextoraw 或编码(例如base64UTL_ENCODE)会更安全。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2022-06-17
    • 2011-12-06
    • 1970-01-01
    • 2015-01-04
    • 2018-04-22
    • 1970-01-01
    • 2011-07-27
    • 1970-01-01
    相关资源
    最近更新 更多