【问题标题】:Why does null <> "something" return false为什么 null <> "something" 返回 false
【发布时间】:2012-09-13 11:31:51
【问题描述】:

当我在一个 oracle 数据库中调试一个过程时,我遇到了一些关于 NULL 值让我感到惊讶的事情。任何人都可以解释为什么下面的查询在这里的不相等检查返回 false 吗?

DECLARE
    vNullVariable VARCHAR2(2) := NULL;
    vVariable VARCHAR2(2) := 'Hi';
BEGIN
    IF vNullVariable <> vVariable THEN
        dbms_output.put_line( 'The variables are not equal' );
    ELSE
        dbms_output.put_line( 'The variables are equal' );
    END IF;
END;

【问题讨论】:

    标签: sql plsql oracle11g


    【解决方案1】:

    这是因为SQL使用了三值逻辑(3VL):有TRUE,有FALSE,还有NULL(未知, 既不是 TRUE 也不是 FALSE)。

    表达式vNullVariable &lt;&gt; vVariable 的结果在 3VL 中为 NULL,而不是 TRUE,因为它认为 vNullVariable 的值是未知的:如果稍后它变成一个已知值,它可能是 'Hi' 或者它可能不是,但现在 SQL 不知道,所以它返回 NULL(未知)。

    所以 IF 表达式的计算结果为 NULL,而不是 TRUE,因此采用默认的 ELSE 路径 - 因为如果 IF 的逻辑是:

    IF <expression is true> THEN
       ...
    ELSE -- ie. if expression is FALSE or NULL
       ...
    END IF;
    

    这意味着如果您以相反的方式编写支票,您得到您所期望的行为:

    IF vNullVariable = vVariable THEN
        dbms_output.put_line( 'The variables are equal' );
    ELSE
        dbms_output.put_line( 'The variables are not equal' );
    END IF;
    

    【讨论】:

    • 有标准的处理方法吗?我并不总是希望该值为 NULL,但无论哪种方式,我都希望执行 IF 块中的代码。我唯一能想到的就是添加类似 (vNullVariable IS NULL AND vVariable IS NOT NULL) AND (.reverse.) AND ( ) 之类的内容。
    • 你可以这样做,或者像我的更新那样做 = 检查而不是 检查。
    • 有时人们使用 nvl:if nvl(v1,'XXX') &lt;&gt; nvl(v2.'XXX') then...。问题当然是你需要使用实际上不可能是真正的非空值的默认值!
    • +1 表示NULL 是未知的,所以我们不能说它不等于'Hi'
    • @Juergen:好吧,结果将是 NULL 而不是 FALSE,但你有一点 - 它会落入 ELSE 中,这可能不是用户所期望的。在这种情况下,我们必须开始使用if (a is null and b is null) or a = b then...
    【解决方案2】:

    NULL 在 Oracle 上有奇怪的行为。要与 null 进行比较,最好使用 IS NULL 而不是 '=NULL'

    Here 你有一个很好的解释

    在您的代码中,您可以使用

    IF vVariable IS NOT NULL THEN
    

    【讨论】:

      【解决方案3】:

      在Oracle 中,NULL 既不等于也不等于NULL。计算两个 NULL 的比较条件将始终为 FALSE。以下涉及 NULL 的条件将是有效的。

      1. IF vNullVariable is NULL THEN
      2. IF vNullVariable is not NULL THEN
      3. IF NVL(vNullVariable, -1) <> NVL(vVariable, -1) THEN -
          This condition will give you expected result even if both vNullVariabl 
          and vVariable are NULLs
      4. Oracle considers two nulls to be equal when evaluating a DECODE function
      

      例如,如果DECODE 函数的第一个和第二个参数是NULLs,则以下查询将为您提供 1

          select decode(null, null, 1) res
            from dual;
      
       res
      -------
        1
      

      【讨论】:

        猜你喜欢
        • 2015-02-22
        • 1970-01-01
        • 2020-06-02
        • 1970-01-01
        • 1970-01-01
        • 2012-06-03
        • 2013-09-18
        • 2014-11-17
        • 2014-03-11
        相关资源
        最近更新 更多