It seems like the simple CASE expression and the DECODE function are equivalent and that the results returned by them should be identical. Are they?
The documentation has the following to say about the simple CASE expression:
The simple CASE expression returns the first result for which
selector_value matches selector. Remaining expressions are not
evaluated. If no selector_value matches selector, the CASE expression
returns else_result if it exists and NULL otherwise.
Comparing this to the DECODE function, the descriptions seem to be identical.
DECODE compares expr to each search value one by one. If expr is equal
to a search, then Oracle Database returns the corresponding result. If
no match is found, then Oracle returns default. If default is omitted,
then Oracle returns null.
As the searched CASE expression can be equivalent to the simple, this could be construed to be the same as well.
These three statements all seem to return the same result, 0.
select case 1 when 2 then null else 0 end as simple_case
, case when 1 = 2 then null else 0 end as searched_case
, decode(1, 2, null, 0) as decode
from dual
Do the simple CASE expression and the DECODE function (and in specific circumstances the searched CASE expression) always return the same result?
Ben has written a lengthy answer on the differences between DECODE and CASE. He demonstrates that DECODE and CASE may return different datatypes for apparently the same set of values without properly explaining why this happens.
DECODE() is quite prescriptive: it is always the datatype of the first result parameter. Oracle applies implicit conversion to all the other result parameters. It will throw an error , if (say) the first result parameter is numeric and the default value is a date.
This is described in the documentation: find out more.
In the first scenario the first result parameter is NULL, which Oracle decides to treat as VARCHAR2. If we change it so that the first result parameter is numeric and the default value is null the DECODE() statement will return a NUMBER; a DUMP() proves that this is so.
Whereas CASE insists that all the returned values have the same datatype, and will throw a compilation error if this is not the case. It won’t apply implicit conversion. This is also covered in the documentation. Read it here.
The difference boils down to this. The following DECODE statement will run, the CASE statement won’t:
Obligatory SQL Fiddle.