Como Phil observou, a string vazia é tratada como NULL, e NULL não é igual ou diferente de nada. Se você espera strings vazias ou NULLs, você precisará lidar com eles com
NVL()
: DECLARE
str1 varchar2(4000);
str2 varchar2(4000);
BEGIN
str1:='';
str2:='sdd';
-- Provide an alternate null value that does not exist in your data:
IF(NVL(str1,'X') != NVL(str2,'Y')) THEN
dbms_output.put_line('The two strings are not equal');
END IF;
END;
/
Em relação a comparações nulas:
De acordo com a documentação do Oracle 12c sobre NULLS, comparações nulas usando
IS NULL
ou IS NOT NULL
avalie como TRUE
ou FALSE
. No entanto, todas as outras comparações são avaliadas como UNKNOWN
, não FALSE
. A documentação ainda informa:
Uma condição avaliada como UNKNOWN age quase como FALSE. Por exemplo, uma instrução SELECT com uma condição na cláusula WHERE avaliada como UNKNOWN não retorna nenhuma linha. No entanto, uma condição avaliada como UNKNOWN difere de FALSE, pois outras operações em uma avaliação de condição UNKNOWN serão avaliadas como UNKNOWN. Assim, NOT FALSE é avaliado como TRUE, mas NOT UNKNOWN é avaliado como UNKNOWN.
Uma tabela de referência é fornecida pela Oracle:
Condition Value of A Evaluation
----------------------------------------
a IS NULL 10 FALSE
a IS NOT NULL 10 TRUE
a IS NULL NULL TRUE
a IS NOT NULL NULL FALSE
a = NULL 10 UNKNOWN
a != NULL 10 UNKNOWN
a = NULL NULL UNKNOWN
a != NULL NULL UNKNOWN
a = 10 NULL UNKNOWN
a != 10 NULL UNKNOWN
Também aprendi que não devemos escrever PL/SQL assumindo que strings vazias sempre serão avaliadas como NULL:
Atualmente, o Oracle Database trata um valor de caractere com comprimento zero como nulo. No entanto, isso pode não continuar sendo verdade em versões futuras, e a Oracle recomenda que você não trate strings vazias da mesma forma que nulas.