当以下任何一项为真时,请使用DECODE
:
- 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
简而言之,根本不要使用DECODE。没有什么是用CASE/WHEN
做不到的。是的,在键盘上会有更多的打字,这是“值得的”。
话虽如此,当我总是喜欢DECODE
时,有一种情况是一次性的,那就是它如何处理NULL
。这种情况是,当我有两个(希望)相同的表,具有相同的键,并且我想找出是否有任何行两个表在列值上不一致。
例如,假设您出于性能原因重写了批处理过程,并且希望确保新版本产生与旧版本相同的结果。在这种情况下,您会认为NULL
和NULL
是相同的“值”DECODE
的行为恰好就是这样。
decode(a, b, Y , N )
将转换为以下case/when构造
case when a = b then Y
when a is null and b is null then Y
else N
end
以下是我的意思的一个例子
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
因此,为了找到不同之处,我会这样做:
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