1

当我在一个 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;
4

3 回答 3

8

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

表达式的结果vNullVariable <> 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;
于 2012-09-13T11:45:03.170 回答
2

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

在这里你有一个很好的解释

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

IF vVariable IS NOT NULL THEN
于 2012-09-13T11:46:33.590 回答
1

在 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函数的第一个和第二个参数是,以下查询将为您提供 1NULLs

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

 res
-------
  1
于 2012-09-13T12:00:29.970 回答