为什么Oracle 9i将空字符串视为NULL?

时间:2008-10-15 02:04:19

标签: sql oracle null string

我知道确实将''视为NULL,但这并没有太多告诉我为什么就是这种情况。据我所知,SQL规范''与NULL不同 - 一个是有效的数据,另一个是缺少相同的信息。

随意推测,但请说明是否属实。如果甲骨文的任何人都可以评论它,那就太棒了!

10 个答案:

答案 0 :(得分:208)

我相信答案是甲骨文非常非常老。

回到有过SQL标准的前几天,Oracle做出了设计决定,即VARCHAR / VARCHAR2列中的空字符串为NULL,并且只有一种感觉NULL(有关系理论家可以区分从未提示过的数据,答案存在但用户不知道的数据,没有答案的数据等等,所有这些都构成{{1 }})。

当SQL标准出现并同意NULL并且空字符串是不同的实体时,已经有Oracle用户拥有代码,假设这两者是等价的。因此Oracle基本上选择了破坏现有代码,违反SQL标准或引入某种初始化参数来改变潜在大量查询的功能。违反SQL标准(恕我直言)是这三个选项中破坏性最小的。

Oracle保留了NULL数据类型在未来版本中将更改以遵守SQL标准的可能性(这就是为什么每个人都在Oracle中使用VARCHAR的原因,因为该数据类型的行为得到保证继续保持不变。)

答案 1 :(得分:56)

Tom Kyte甲骨文副总裁:

  

ZERO长度varchar被视为   NULL。

     

''不被视为NULL。

     当分配给char(1)时,

''变为   ''(字符类型为空白填充   字符串)。

     分配给varchar2(1)时

''   成为''这是一个零长度   字符串和零长度字符串   Oracle中的NULL(不久')

答案 2 :(得分:19)

我怀疑如果你像早期的开发人员那样想到Oracle,这会更有意义 - 作为数据输入系统的美化后端。数据库中的每个字段对应于数据输入操作员在其屏幕上看到的表单中的字段。如果操作员没有在字段中输入任何内容,无论是“生日”还是“地址”,那么该字段的数据都是“未知”。对于操作员来说,没有办法表明某人的地址确实是一个空字符串,而且这无论如何都没有多大意义。

答案 3 :(得分:17)

Oracle文档提醒开发人员注意这个问题,至少可以追溯到版本7。

Oracle选择通过“不可能的价值”技术代表NULLS。例如,数字位置中的NULL将存储为“减零”,这是一个不可能的值。计算产生的任何负零将在存储之前转换为正零。

Oracle也错误地选择将长度为零的VARCHAR字符串(空字符串)视为不可能的值,并且是表示NULL的合适选择。事实证明,空字符串远非一个不可能的值。它甚至是字符串连接操作下的身份!

Oracle文档警告数据库设计人员和开发人员可能会使用Oracle的未来版本 打破空字符串和NULL之间的这种关联,并打破依赖于该关联的任何代码。

除了不可能的值之外,还有一些技术可以标记NULLS,但Oracle并没有使用它们。

(我在上面使用“位置”一词表示行和列的交集。)

答案 4 :(得分:2)

空字符串与NULL相同,因为它与两个(空字符串和null)不相同时的情况相比,它是“较小的邪恶”。

在NULL和空字符串不相同的语言中,必须始终检查两个条件。

答案 5 :(得分:0)

According to official 11g docs

  

Oracle数据库当前将长度为零的字符值视为null。但是,在将来的版本中可能不会继续这样,Oracle建议您不要将空字符串视为空值。

可能的原因

  1. val IS NOT NULLval != ''
  2. 更具可读性
  3. 无需检查两个条件val != '' and val IS NOT NULL

答案 6 :(得分:0)

书中的例子

   set serveroutput on;   
    DECLARE
    empty_varchar2 VARCHAR2(10) := '';
    empty_char CHAR(10) := '';
    BEGIN
    IF empty_varchar2 IS NULL THEN
    DBMS_OUTPUT.PUT_LINE('empty_varchar2 is NULL');
    END IF;


    IF '' IS NULL THEN
    DBMS_OUTPUT.PUT_LINE(''''' is NULL');
    END IF;

    IF empty_char IS NULL THEN
    DBMS_OUTPUT.PUT_LINE('empty_char is NULL');
    ELSIF empty_char IS NOT NULL THEN
    DBMS_OUTPUT.PUT_LINE('empty_char is NOT NULL');
    END IF;

    END;

答案 7 :(得分:-1)

因为不将它视为NULL也不是特别有用。

如果您在Oracle上的这个区域出错,您通常会立即注意到。但是,在SQL服务器中,它似乎可以工作,只有当有人输入空字符串而不是NULL(可能来自.net客户端库,其中null与“”不同时,问题才出现,但您通常会将它们视为相同)。

我不是说甲骨文是正确的,但在我看来,两种方式都差不多。

答案 8 :(得分:-6)

事实上,我只有处理Oracle的困难,包括无效的日期时间值(无法打印,转换或任何东西,只需用DUMP()函数查看)允许到被插入到数据库中,显然是通过客户端的一些错误版本作为二进制列!这么多是为了保护数据库的完整性!

Oracle处理NULLs链接:

http://digitalbush.com/2007/10/27/oracle-9i-null-behavior/

http://jeffkemponoracle.com/2006/02/empty-string-andor-null.html

答案 9 :(得分:-6)

首先,Oracle和null并不总是将null和null字符串视为相同。根据定义,空字符串是不包含字符的字符串。这与null完全不同。根据定义,NULL是缺少数据的。

五六年前,Oracle对null字符串的处理方式与null不同。虽然像null一样,null字符串等于所有内容并且与所有内容不同(我认为对于null很好,但对于空字符串完全是WRONG),至少length(null字符串)将返回0,因为它应该是因为null string是一个零长度的字符串。

目前在Oracle中,length(null)返回null,我猜是O.K.,但length(null string)也返回null,这完全是错误的。

我不明白为什么他们决定开始对这两个不同的“价值观”进行相同的处理。它们意味着不同的东西,程序员应该能够以不同的方式对每个事物采取行动。事实上,他们已经改变了他们的方法论,这告诉我他们真的不知道如何处理这些价值观。