代码之家  ›  专栏  ›  技术社区  ›  Steve B.

Oracle不区分空字符串和空字符串?

  •  14
  • Steve B.  · 技术社区  · 15 年前

    显然oracle似乎无法区分空字符串和空字符串。例如。

    Select name from TABLE_A where id=100;
      ID   NAME
      100  null
    
    Update TABLE_A set NAME='' where id=100;
    SELECT -->
      ID   NAME
      100  null
    
    SELECT length(NAME) FROM TABLE_A WHERE id=100;
      null
    

    是否至少要区分0长度和未定义长度?这是一个已知的问题吗?出于特定目的的故意行为?数据库理论的长期争论?有什么好处?

    this question .)

    5 回复  |  直到 7 年前
        1
  •  33
  •   Community CDub    8 年前

    Oracle 他很老了。

    回到 80's 当它被开发出来的时候(在没有任何标准之前),他们认为这是一个好主意,然后就放弃了 存储它的值,它确实是。

    这是怎么做的 神谕 存储数据(取自 documentation ):

    alt text

    数据中不存储数据类型,只存储数据长度和数据本身。

    NULL 在具有值的两列之间发生,它存储为单字节,表示列具有长度 0 0xFF ).拖尾 一点也不存储。

    所以要存储值 'test' , 需要存储5个字节: 04 74 65 73 74 .

    但是,要同时存储空字符串和 无效的 , .

    如果您的数据要存储在 20 Mb 5,000$

    后来,当标准出现时,它不再是一个好主意,但到那时已经有很多代码依赖于它 '' 是一样的。

    VARCHAR 做这样的区分将会打破 代码的定义。

    为了解决这个问题,他们重新命名了 瓦尔查尔 VARCHAR2 (不属于任何标准的一部分),声明 瓦查尔2 区别 无效的

    现在,他们可能正在等待最后一个使用 在里面 神谕

        2
  •  3
  •   Rob van Wijk    15 年前

    您可能想阅读两年多前在OTN上关于这个主题的冗长且有时有趣的讨论: http://forums.oracle.com/forums/thread.jspa?threadID=456874&start=0&tstart=0

    抢劫

        3
  •  1
  •   Erwin Smout Erwin Smout    15 年前

    (不,我必须准确地说。事实上,这只是他在过去几十年中提到的支持这一主张的几乎数百个理由中的一个。)

    编辑

    “让VARCHAR做这样的区分将破坏成吨的代码。”

    是的,当然,在每次更新时用null替换“空字符串”,至少打破了标准的精神,这是一个较小的罪恶?

    (注意:null不等于任何值,甚至不等于它本身,因此在将空字符串赋给列后,oracle将在该列中为您提供一个与您所说的要显示在该列中的值不同的值。哇。)

        4
  •  0
  •   Ian Carpenter    15 年前

    看起来甲骨文已经说过,这种行为可能会在未来的版本中发生改变。何时发布以及发布的版本没有提及。

    如果您无法访问metalink,请参阅10g版本2文档中的以下内容 here

        5
  •  0
  •   tuinstoel    15 年前

    Oracle触发器可以引用在其上创建触发器的表:

    create table t (id number(10) );
    
    create or replace trigger  t_bir before insert  on  t for each row
    declare
      l_id t.id%type;
    begin
      select id
      into   l_id
      from   t
      where  id = :new.id;
    exception
      when no_data_found then 
        null;
    end;
    /
    
    
    SQL> insert into t values (20);
    
    1 row is created.
    
    
    SQL> select * from t;
    
            ID
    ----------
            20