Use DECODE
when any of the following is true:
- You want to write non-portable SQL
- You want to to write code that only Oracle developers recognize and understand
- You want to write code that is hard to read
- You want to increase the chance of introducing bugs the next time you change the code
- You want the optimizer to generate suboptimal execution plans (when used in where-clause).
- You are writing throw-away code
In short, don't use DECODE at all. There is nothing it can't do that couldn't be done with a CASE/WHEN
. Yes, there will be more typing at the keyboard, and it is "worth" it.
Having said that, there is one throw-away case when I always prefer DECODE
, that has to do with how it deals with NULL
. The scenario is when I have two (hopefully) identical tables with the same key, and when I want to find out if there are any rows where the two tables don't agree on a column value.
For example, let's say you have rewritten a batch procedure for performance reasons, and you want to make sure that the new version produces the same results as the old version. In this situation, you would consider NULL
and NULL
to be the same "value". DECODE
happens to behave just like that.
decode(a, b, 'Y', 'N')
would translate to the following case/when construct
case when a = b then 'Y'
when a is null and b is null then 'Y'
else 'N'
end
Here is an example of what I mean
with old_table as(
select 1 as id, 'A' as old_col from dual union all
select 2 as id, 'A' as old_col from dual union all
select 3 as id, 'A' as old_col from dual union all
select 4 as id, null as old_col from dual
)
,new_table as(
select 1 as id, 'A' as new_col from dual union all
select 2 as id, 'B' as new_col from dual union all
select 3 as id, null as new_col from dual union all
select 4 as id, null as new_col from dual
)
select id
,old_col
,new_col
,decode(old_col, new_col, 'Y', 'N') as has_same_val
from old_table
join new_table using(id);
ID OLD_COL NEW_COL HAS_SAME_VAL
-- ------- ------- ------------
1 A A Y
2 A B N
3 A null N <-- Note those
4 null null Y <-- two cases
So to find the difference I would do:
where decode(old_col1, new_col1, 'same', 'diff') = 'diff'
or decode(old_col2, new_col2, 'same', 'diff') = 'diff'
or decode(old_col3, new_col3, 'same', 'diff') = 'diff'
or decode(old_col4, new_col4, 'same', 'diff') = 'diff'
or decode(old_col5, new_col5, 'same', 'diff') = 'diff'