1).Hello, I have the following Oracle PL/SQL codes that may be rusty from you guys perspective:
DECLARE
str1 varchar2(4000);
str2 varchar2(4000);
BEGIN
str1:='';
str2:='sdd';
IF(str1<>str2) THEN
dbms_output.put_line('The two strings is not equal');
END IF;
END;
/
This is very obvious that two strings str1 and str2 are not equal, but why 'The two strings are not equal' was not printed out? Do Oracle have another common method to compare two string?
To the first question:
Probably the message wasn't print out because you have the output turned off. Use these commands to turn it back on:
On the second question:
My PLSQL is quite rusty so I can't give you a full snippet, but you'll need to loop over the result set of the SQL query and CONCAT all the strings together.
I compare strings using
=
and not<>
. I've found out that in this context=
seems to work in more reasonable fashion than<>
. I have specified that two empty (or NULL) strings are equal. The real implementation returns PL/SQL boolean, but here I changed that to pls_integer (0 is false and 1 is true) to be able easily demonstrate the function.To fix the core question, "how should I detect that these two variables don't have the same value when one of them is null?", I don't like the approach of
nvl(my_column, 'some value that will never, ever, ever appear in the data and I can be absolutely sure of that')
because you can't always guarantee that a value won't appear... especially with NUMBERs.I have used the following:
Disclaimer: I am not an Oracle wizard and I came up with this one myself and have not seen it elsewhere, so there may be some subtle reason why it's a bad idea. But it does avoid the trap mentioned by APC, that comparing a null to something else gives neither TRUE nor FALSE but NULL. Because the clauses
(str1 is null)
will always return TRUE or FALSE, never null.(Note that PL/SQL performs short-circuit evaluation, as noted here.)
As Phil noted, the empty string is treated as a NULL, and NULL is not equal or unequal to anything. If you expect empty strings or NULLs, you'll need to handle those with
NVL()
:Concerning null comparisons:
According to the Oracle 12c documentation on NULLS, null comparisons using
IS NULL
orIS NOT NULL
do evaluate toTRUE
orFALSE
. However, all other comparisons evaluate toUNKNOWN
, notFALSE
. The documentation further states:A reference table is provided by Oracle:
I also learned that we should not write PL/SQL assuming empty strings will always evaluate as NULL:
I've created a stored function for this text comparison purpose:
In example:
Let's fill in the gaps in your code, by adding the other branches in the logic, and see what happens:
So the two strings are neither the same nor are they not the same? Huh?
It comes down to this. Oracle treats an empty string as a NULL. If we attempt to compare a NULL and another string the outcome is not TRUE nor FALSE, it is NULL. This remains the case even if the other string is also a NULL.