Reputation: 5825
I was debugging a procedure in an oracle database when I came across something that surprised me regarding NULL values. Can anybody explain why the following query returns false for the non equality check here?
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;
Upvotes: 1
Views: 1810
Reputation: 27261
In Oracle, NULL is neither equal to nor not equal to NULL. A comparison condition that evaluates two NULLs will always be FALSE. The following conditions involving NULL will be valid.
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
for example the following query will give you 1 if first and second arguments of DECODE
function are NULLs
select decode(null, null, 1) res
from dual;
res
-------
1
Upvotes: 1
Reputation: 132680
This is because SQL uses three-valued logic (3VL): there is TRUE, there is FALSE and there is NULL (unknown, neither TRUE nor FALSE).
The result of the expression vNullVariable <> vVariable
is NULL, not TRUE, in 3VL because it considers the value of vNullVariable to be unknown: if at a later time it becomes a known value, it might be 'Hi' or it might not, but right now SQL doesn't know so it returns NULL (unknown).
So the IF expression evaluates to NULL, not TRUE, and so the default ELSE path is taken instead - because the logic if IF is:
IF <expression is true> THEN
...
ELSE -- ie. if expression is FALSE or NULL
...
END IF;
This means that you would get the behaviour you were expecting if you wrote the check the other way around:
IF vNullVariable = vVariable THEN
dbms_output.put_line( 'The variables are equal' );
ELSE
dbms_output.put_line( 'The variables are not equal' );
END IF;
Upvotes: 8