我知道它确实认为' '为NULL,但这并没有告诉我为什么会这样。根据我对SQL规范的理解,' '与NULL不一样——一个是有效的数据,另一个是表明没有相同的信息。

请随意猜测,但如果是这样,请指出来。如果甲骨文有谁能对此发表评论,那就太棒了!


当前回答

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

Oracle选择用“不可能值”技术来表示null。例如,数值位置中的NULL将被存储为“负零”,这是一个不可能的值。任何由计算产生的负0将在存储之前转换为正0。

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

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

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

(我上面用的“位置”这个词是指行和列的交点。)

其他回答

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

早在SQL标准出现之前,Oracle的设计决定是VARCHAR/VARCHAR2列中的空字符串为NULL,并且只有一种意义上的NULL(有关系理论家会区分从未提示的数据、存在答案但用户不知道的数据、没有答案的数据等等,所有这些都构成了某种意义上的NULL)。

By the time that the SQL standard came around and agreed that NULL and the empty string were distinct entities, there were already Oracle users that had code that assumed the two were equivalent. So Oracle was basically left with the options of breaking existing code, violating the SQL standard, or introducing some sort of initialization parameter that would change the functionality of potentially large number of queries. Violating the SQL standard (IMHO) was the least disruptive of these three options.

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

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

Oracle选择用“不可能值”技术来表示null。例如,数值位置中的NULL将被存储为“负零”,这是一个不可能的值。任何由计算产生的负0将在存储之前转换为正0。

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

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

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

(我上面用的“位置”这个词是指行和列的交点。)

书中的例子

   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;

因为不将其处理为NULL也不是特别有用。

如果你在Oracle上在这方面犯了错误,你通常会马上注意到。然而,在SQL server中,它似乎是可以工作的,并且只有当有人输入空字符串而不是NULL时才会出现问题(可能来自。net客户端库,其中NULL与“”不同,但您通常将它们视为相同的)。

我并不是说甲骨文是对的,但在我看来,这两种方法都差不多一样糟糕。

I suspect this makes a lot more sense if you think of Oracle the way earlier developers probably did -- as a glorified backend for a data entry system. Every field in the database corresponded to a field in a form that a data entry operator saw on his screen. If the operator didn't type anything into a field, whether that's "birthdate" or "address" then the data for that field is "unknown". There's no way for an operator to indicate that someone's address is really an empty string, and that doesn't really make much sense anyways.