Krótka odpowiedź, nie.
Nieco dłuższa odpowiedź jest prawie.
Tylko pojawia się że wynik uzyskany z każdego stwierdzenia jest identyczny. Jeśli użyjemy funkcji DUMP do oceny zwróconych typów danych, zobaczysz, co mam na myśli:
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
Skrzypce SQL
Możesz zobaczyć, że typ danych DECODE to 1, podczas gdy dwie instrukcje CASE "zwracają" typ danych 2. Korzystając z podsumowania typów danych Oracle, DECODE zwraca VARCHAR2 (typ danych 1), podczas gdy instrukcje CASE "zwracają " liczby (typ danych 2).
Zakładam, że dzieje się tak, ponieważ, jak sugerują nazwy, DECODE to funkcja a CASE nie, co oznacza, że zostały wewnętrznie zaimplementowane inaczej. Nie ma prawdziwego sposobu, aby to udowodnić.
Możesz pomyśleć, że to tak naprawdę na nic nie wpływa. Jeśli potrzebujesz liczby, Oracle niejawnie skonwertuje znak na liczbę zgodnie z regułami niejawnej konwersji, prawda? To też nie jest prawdą, nie będzie działać w UNION, tak jak typy danych mają być identyczne; Oracle nie dokona żadnej niejawnej konwersji, aby ułatwić Ci pracę. Po drugie, oto co Oracle mówi o konwersji niejawnej:
Oracle zaleca, aby określić jawne konwersje, zamiast polegać na niejawnych lub automatycznych konwersjach, z następujących powodów:
-
Instrukcje SQL są łatwiejsze do zrozumienia, gdy używasz jawnych funkcji konwersji typów danych.
-
Niejawna konwersja typu danych może mieć negatywny wpływ na wydajność, zwłaszcza jeśli typ danych wartości kolumny jest konwertowany na wartość stałą, a nie na odwrót.
-
Konwersja niejawna zależy od kontekstu, w którym występuje i może nie działać w ten sam sposób w każdym przypadku. Na przykład niejawna konwersja z wartości daty i godziny na wartość VARCHAR2 może zwrócić nieoczekiwany rok w zależności od wartości parametru NLS_DATE_FORMAT.
-
Algorytmy konwersji niejawnej mogą ulec zmianie w różnych wersjach oprogramowania i produktów Oracle. Zachowanie jawnych konwersji jest bardziej przewidywalne.
To nie jest ładna lista; ale przedostatni punkt ładnie prowadzi mnie na randki. Jeśli weźmiemy poprzednie zapytanie i przekonwertujemy je na takie, które zamiast tego używa daty:
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;
Ponownie, używając DUMP w tym zapytaniu, instrukcje CASE zwracają typ danych 12, DATE. DECODE przekonwertował sysdate
w 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
Skrzypce SQL
Zauważ (w SQL Fiddle), że DATE została przekonwertowana na znak przy użyciu sesji NLS_DATE_FORMAT.
Posiadanie daty, która została niejawnie przekonwertowana na VARCHAR2 może powodować problemy. Jeśli zamierzasz użyć TO_CHAR, aby przekonwertować datę na znak, Twoje zapytanie zostanie przerwane tam, gdzie się tego nie spodziewasz.
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
Skrzypce SQL
Podobnie, arytmetyka dat już nie działa:
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
Skrzypce SQL
Co ciekawe DECODE konwertuje wyrażenie na VARCHAR2 tylko wtedy, gdy jeden z możliwych wyników jest NULL. Jeśli domyślna wartość to NULL, to tak się nie dzieje. Na przykład:
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
Skrzypce SQL
Zauważ, że DECODE zwrócił typ danych 13. Nie jest to udokumentowane, ale zakładam, że jest to typ daty, jak działa arytmetyka dat itp.
Krótko mówiąc, unikaj DEKODOWANIA, jeśli możesz; niekoniecznie otrzymasz oczekiwane typy danych. Cytując Toma Kyte'a:
Dekodowanie jest nieco niejasne -- CASE jest bardzo jasne. Rzeczy, które są łatwe do zrobienia w dekodowaniu, są łatwe do zrobienia w CASE, rzeczy, które są trudne lub prawie niemożliwe do zrobienia za pomocą dekodowania, są łatwe do zrobienia w CASE. CASE logicznie wygrywa.
Aby być kompletnym, są dwa funkcjonalne różnice między DECODE i CASE.
- DECODE nie może być używany w PL/SQL.
-
CASE nie może być używany do bezpośredniego porównywania wartości null
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
Skrzypce SQL