Jawaban singkat, tidak.
Jawaban yang sedikit lebih panjang hampir.
Hanya muncul bahwa hasil yang diperoleh dari setiap pernyataan adalah identik. Jika kita menggunakan fungsi DUMP untuk mengevaluasi tipe data yang dikembalikan, Anda akan mengerti maksud saya:
SQL> select dump(case 1 when 2 then null else 0 end) as simple_case
2 , dump(case when 1 = 2 then null else 0 end) as searched_case
3 , dump(decode(1, 2, null, 0)) as decode
4 from dual;
SIMPLE_CASE SEARCHED_CASE DECODE
------------------ ------------------ -----------------
Typ=2 Len=1: 128 Typ=2 Len=1: 128 Typ=1 Len=1: 48
SQL Fiddle
Anda dapat melihat bahwa tipe data DECODE adalah 1, sedangkan dua pernyataan KASUS "mengembalikan" tipe data 2. Menggunakan Ringkasan Tipe Data Oracle, DECODE mengembalikan VARCHAR2 (tipe data 1) sedangkan pernyataan KASUS adalah "mengembalikan " angka (tipe data 2).
Saya berasumsi ini terjadi karena, seperti namanya, DECODE adalah fungsi dan CASE tidak, yang menyiratkan bahwa mereka telah diimplementasikan secara berbeda secara internal. Tidak ada cara nyata untuk membuktikan ini.
Anda mungkin berpikir bahwa ini tidak benar-benar memengaruhi apa pun. Jika Anda membutuhkannya sebagai angka, Oracle akan secara implisit mengonversi karakter menjadi angka di bawah aturan konversi implisit, bukan? Ini juga tidak benar, ini tidak akan berfungsi di UNION karena tipe data memiliki menjadi identik; Oracle tidak akan melakukan konversi implisit untuk mempermudah Anda. Kedua, inilah yang dikatakan Oracle tentang konversi implisit:
Oracle menyarankan agar Anda menentukan konversi eksplisit, daripada mengandalkan konversi implisit atau otomatis, karena alasan berikut:
Pernyataan SQL lebih mudah dipahami saat Anda menggunakan fungsi konversi tipe data eksplisit.
Konversi tipe data implisit dapat berdampak negatif pada performa, terutama jika tipe data dari nilai kolom diubah menjadi konstanta, bukan sebaliknya.
Konversi implisit tergantung pada konteks di mana itu terjadi dan mungkin tidak bekerja dengan cara yang sama dalam setiap kasus. Misalnya, konversi implisit dari nilai datetime ke nilai VARCHAR2 dapat menghasilkan tahun yang tidak terduga bergantung pada nilai parameter NLS_DATE_FORMAT.
Algoritma untuk konversi implisit dapat berubah di seluruh rilis perangkat lunak dan di antara produk Oracle. Perilaku konversi eksplisit lebih dapat diprediksi.
Itu bukan daftar yang bagus; tetapi poin kedua dari belakang membawa saya dengan baik ke kencan. Jika kita mengambil kueri sebelumnya dan mengonversinya menjadi kueri yang menggunakan tanggal sebagai gantinya:
select case sysdate when trunc(sysdate) then null
else sysdate
end as simple_case
, case when sysdate = trunc(sysdate) then null
else sysdate
end as searched_case
, decode(sysdate, trunc(sysdate), null, sysdate) as decode
from dual;
Sekali lagi, menggunakan DUMP pada kueri ini, pernyataan CASE mengembalikan tipe data 12, sebuah DATE. DECODE telah mengonversi sysdate
menjadi VARCHAR2.
SQL> select dump(case sysdate when trunc(sysdate) then null
2 else sysdate
3 end) as simple_case
4 , dump(case when sysdate = trunc(sysdate) then null
5 else sysdate
6 end) as searched_case
7 , dump(decode(sysdate, trunc(sysdate), null, sysdate)) as decode
8 from dual;
SIMPLE_CASE
----------------------------------
Typ=12 Len=7: 120,112,12,4,22,18,7
SEARCHED_CASE
----------------------------------
Typ=12 Len=7: 120,112,12,4,22,18,7
DECODE
----------------------------------
Typ=1 Len=19: 50,48,49,50,45,49,50,45,48,52,32,50,49,58,49,55,58,48,54
SQL Fiddle
Perhatikan (dalam SQL Fiddle) bahwa DATE telah diubah menjadi karakter menggunakan sesi NLS_DATE_FORMAT.
Memiliki tanggal yang secara implisit diubah menjadi VARCHAR2 dapat menyebabkan masalah. Jika Anda bermaksud menggunakan TO_CHAR, untuk mengonversi tanggal menjadi karakter, kueri Anda akan pecah di tempat yang tidak Anda harapkan.
SQL> select to_char( decode( sysdate
2 , trunc(sysdate), null
3 , sysdate )
4 , 'yyyy-mm-dd') as to_char
5 from dual;
select to_char( decode( sysdate
*
ERROR at line 1:
ORA-01722: invalid number
SQL Fiddle
Demikian pula, aritmatika tanggal tidak lagi berfungsi:
SQL>
SQL>
SQL> select decode(sysdate, trunc(sysdate), null, sysdate) + 1 as decode
2 from dual;
select decode(sysdate, trunc(sysdate), null, sysdate) + 1 as decode
*
ERROR at line 1:
ORA-01722: invalid number
SQL Fiddle
Menariknya DECODE hanya mengubah ekspresi menjadi VARCHAR2 jika salah satu hasil yang mungkin adalah NULL. Jika nilai default adalah NULL maka ini tidak terjadi. Misalnya:
SQL> select decode(sysdate, sysdate, sysdate, null) as decode
2 from dual;
DECODE
-------------------
2012-12-04 21:18:32
SQL> select dump(decode(sysdate, sysdate, sysdate, null)) as decode
2 from dual;
DECODE
------------------------------------------
Typ=13 Len=8: 220,7,12,4,21,18,32,0
SQL Fiddle
Perhatikan bahwa DECODE telah mengembalikan tipe data 13. Ini tidak didokumentasikan tetapi, menurut saya, merupakan tipe tanggal karena aritmatika tanggal, dll. berfungsi.
Singkatnya, hindari DECODE jika Anda bisa; Anda mungkin belum tentu mendapatkan tipe data yang Anda harapkan. Mengutip Tom Kyte:
Decode agak tidak jelas -- CASE sangat sangat jelas. Hal-hal yang mudah dilakukan dalam decode mudah dilakukan di CASE, hal-hal yang sulit atau hampir tidak mungkin dilakukan dengan decode mudah dilakukan di CASE. CASE, secara logika, menang telak.
Untuk melengkapinya ada dua fungsional perbedaan antara DECODE dan CASE.
- DECODE tidak dapat digunakan dalam PL/SQL.
-
CASE tidak dapat digunakan untuk membandingkan null secara langsung
SQL> select case null when null then null else 1 end as case1 2 , case when null is null then null else 1 end as case2 3 , decode(null, null, null, 1) as decode 4 from dual 5 ; CASE1 CASE2 DECODE ---------- ---------- ------ 1
SQL Fiddle