为什么null<> “某事”回归虚假

时间:2012-09-13 11:31:51

标签: sql plsql oracle11g

当我遇到一些让我对NULL值感到惊讶的事情时,我正在调试oracle数据库中的一个过程。任何人都可以解释为什么以下查询在这里为非等式检查返回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;

3 个答案:

答案 0 :(得分:8)

这是因为SQL使用三值逻辑(3VL): TRUE FALSE 并且 NULL (未知) ,既不是真也不是假。)

表达式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;

答案 1 :(得分:2)

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

Here 你对

有一个很好的解释

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

IF vVariable IS NOT NULL THEN

答案 2 :(得分: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函数的第一个和第二个参数为NULLs

,则以下查询将为您提供1
    select decode(null, null, 1) res
      from dual;

 res
-------
  1