3
votes

Hi today I have met with weird situation. I had a where clause where was condition which returns String and I wanted to check if it's empty or not. And when it returns empty string Oracle still treat it like a different Strings. So I went further and prepared simple queries:

select 1 from dual where 1 = 1;
returns: 1

select 1 from dual where 'A' = 'A';
returns: 1

And now what I cannot understand:

select 1 from dual where '' = '';
No result.

Even if I check if they are different there is still no result.

select 1 from dual where '' != '';
No result.

Can someone explain it for me ?

2
Empty string are the same as nulls in Oracle. See this question, and the docs, particularly the part about comparisons. - Alex Poole
@AlexPoole Thanks for the links to the documents. Many people have opinions, facts are always welcome. The really curious thing is that, unlike much of Oracle's documentation, this one is clear! - Brian Leach

2 Answers

4
votes

Oracle treats empty strings as NULL. It's a gotcha. Make a note of it and hope it never bites you in the butt in production.

4
votes

The reason is as @Captain Kenpachi explained. If want to compare two strings (or other types that are the same) and want to be tolerant of NULLs (or empty string in Oracle as it treats it as the same) then you need to involve an IS test.

You could try the common cheat of using a rogue value that will never be used but Murphy's Law dictates that one day someone will. This technique also has the drawback that the rogue value should match the type of the thing you are comparing i.e. comparing strings you need a rogue string while comparing dates you need a rouge date. This also means you can't cut-and-paste it liberally without applying a little thought. Example: WHERE NVL(col1,'MyRougeValue')=NVL(col2,'MyRougeValue')

The standard version is to explicitly test for NULLs WHERE (col1=col2 OR (col1 IS NULL AND col2 IS NULL))

The opposite becomes WHERE NOT(col1=col2 OR (col1 IS NULL AND col2 IS NULL))

I have seen the a long winded opposite version (as seen in Toad's data compare tool) WHERE (col1<>col2 OR (col1 IS NULL AND col2 IS NOT NULL) OR (col1 IS NOT NULL AND col2 IS NULL))

Oracle does have a handy DECODE function that is basically is IF a IS b THEN c ELSE d so equality is WHERE DECODE(col1,col2,1,0)=1 and the opposite is WHERE DECODE(col1,col2,1,0)=0. You may find this a little slower than the explicit IS test. It is proprietary to Oracle but helps make up for the empty string problem.