一尘不染

CASE 语句和 DECODE 是否等效?

sql

看起来简单的 CASE 表达式和 DECODE 函数是等效的,它们返回的结果应该是相同的。他们是吗?

该文档对简单的 CASE 表达式有以下说明:

简单的 CASE 表达式返回 selector_value 匹配选择器的第一个结果。不评估剩余的表达式。如果没有 selector_value 匹配选择器,则 CASE 表达式如果存在则返回 else_result,否则返回 NULL。

将其与DECODE 函数进行比较,描述似乎是相同的。

DECODE 将 expr 与每个搜索值一一比较。如果 expr 等于搜索,则 Oracle 数据库返回相应的结果。如果未找到匹配项,则 Oracle 返回默认值。如果省略 default,则 Oracle 返回 null。

由于搜索到的 CASE 表达式可以等同于简单的,这也可以解释为相同。

这三个语句似乎都返回相同的结果 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

简单的 CASE 表达式和 DECODE 函数(以及在特定情况下搜索的 CASE 表达式)是否总是返回相同的结果?


阅读 479

收藏
2021-07-01

共1个答案

一尘不染

Ben 写了一篇关于 DECODE 和 CASE 之间差异的冗长答案。他演示了 DECODE 和 CASE 可能会为明显相同的一组值返回不同的数据类型,而没有正确解释为什么会发生这种情况。

DECODE() 非常规范:它始终是第一个结果参数的数据类型。Oracle 将隐式转换应用于所有其他结果参数。如果(比如说)第一个结果参数是数字并且默认值是日期,它会抛出一个错误。

ORA-00932: inconsistent datatypes: expected NUMBER got DATE

在第一种情况下,第一个结果参数是 NULL,Oracle 决定将其视为 VARCHAR2。如果我们将其更改为第一个结果参数为数字且默认值为空,则 DECODE() 语句将返回 NUMBER;DUMP() 证明确实如此。

而 CASE 坚持所有返回的值都具有相同的数据类型,如果不是这种情况,则会抛出编译错误。它不会应用隐式转换。

差异归结为这一点。以下 DECODE 语句将运行,CASE 语句不会:

select decode(1, 1, 1, '1') from dual;

select case 1 when 1 then 1 else '1' end from dual;
2021-07-01