Czy istnieją nieoczywiste różnice między NVL a Coalesce w Oracle?
Oczywiste różnice polegają na tym, że łączenie zwróci pierwszy niepusty element na liście parametrów, podczas gdy nvl przyjmuje tylko dwa parametry i zwraca pierwszy, jeśli nie jest pusty, w przeciwnym razie zwraca drugi.
Wygląda na to, że NVL może być po prostu wersją koalescencji w „przypadku podstawowym”.
Czy coś brakuje?
Odpowiedzi:
COALESCE
jest bardziej nowoczesną funkcją będącą częściąANSI-92
standardu.NVL
jestOracle
specyficzny, został wprowadzony80
zanim pojawiły się jakiekolwiek standardy.W przypadku dwóch wartości są to synonimy.
Są one jednak wdrażane inaczej.
NVL
zawsze ocenia oba argumenty, podczas gdyCOALESCE
zwykle zatrzymuje ocenę za każdym razem, gdy znajdzie pierwszą inną niżNULL
(istnieją pewne wyjątki, takie jak sekwencjaNEXTVAL
):Działa to prawie przez
0.5
kilka sekund, ponieważ generujeSYS_GUID()
s, mimo1
że nie jestNULL
.To rozumie, że
1
to nie jestNULL
i nie ocenia drugiego argumentu.SYS_GUID
nie są generowane, a zapytanie jest natychmiastowe.źródło
NVL dokona niejawnej konwersji na typ danych pierwszego parametru, więc poniższe błędy nie powodują błędu
COALESCE oczekuje spójnych typów danych.
zgłasza „niespójny błąd typu danych”
źródło
NVL i COALESCE są używane do osiągnięcia tej samej funkcjonalności, co zapewnienie wartości domyślnej w przypadku, gdy kolumna zwraca NULL.
Różnice są następujące:
Przykłady trzeciego przypadku. Inne przypadki są proste.
select nvl('abc',10) from dual;
działałoby, ponieważ NVL wykona niejawną konwersję liczby 10 na ciąg.select coalesce('abc',10) from dual;
zakończy się niepowodzeniem z błędem - niespójne typy danych: oczekiwany CHAR ma NUMBERPrzykład przypadku użycia UNION
nie działa z
ORA-00932: inconsistent datatypes: expected CHAR got DATE
udaje się.
Więcej informacji: http://www.plsqlinformation.com/2016/04/difference-between-nvl-and-coalesce-in-oracle.html
źródło
Istnieje również różnica w obsłudze planu.
Oracle jest w stanie stworzyć zoptymalizowany plan z konkatenacją filtrów oddziałów, gdy wyszukiwanie zawiera porównanie
nvl
wyników z kolumną indeksowaną.nvl:
łączyć:
Kredyty są dostępne na stronie http://www.xt-r.com/2012/03/nvl-coalesce-concatenation.html .
źródło
Kolejny dowód na to, że coalesce () nie zatrzymuje oceny z pierwszą wartością inną niż null:
Uruchom to, a następnie sprawdź
my_sequence.currval;
źródło
Właściwie nie mogę zgodzić się na każde oświadczenie.
„COALESCE oczekuje, że wszystkie argumenty będą tego samego typu danych”.
To źle, patrz poniżej. Argumenty mogą być różnymi typami danych, co jest również udokumentowane : Jeśli wszystkie wystąpienia wyrażenia są liczbowym typem danych lub dowolnym nieliczbowym typem danych, który można niejawnie przekonwertować na numeryczny typ danych, wówczas baza danych Oracle określa argument o najwyższym pierwszeństwie liczbowym, niejawnie konwertuje pozostałe argumenty na ten typ danych i zwraca ten typ danych.. W rzeczywistości jest to nawet sprzeczne z powszechnym wyrażeniem „COALESCE zatrzymuje się przy pierwszym wystąpieniu wartości innej niż Null”, w przeciwnym razie przypadek testowy nr 4 nie powinien zgłaszać błędu.
Również zgodnie z przypadkiem testowym nr 5
COALESCE
dokonuje domyślnej konwersji argumentów.źródło
Chociaż ten jest oczywisty, a nawet wspomniany w sposób postawiony przez Toma, który zadał to pytanie. Ale odłóżmy jeszcze raz.
NVL może mieć tylko 2 argumenty. Łączenie może mieć więcej niż 2.
select nvl('','',1) from dual;
// Wynik::ORA-00909
nieprawidłowa liczba argumentów // Wynikselect coalesce('','','1') from dual;
: zwraca 1źródło
NVL: Zamień null na wartość.
ŁĄCZYĆ: Zwraca pierwsze niepuste wyrażenie z listy wyrażeń.
Tabela: PRICE_LIST
Poniżej znajduje się przykład
[1] Ustaw cenę sprzedaży z dodaniem 10% zysku do wszystkich produktów.
[2] Jeśli nie ma ceny zakupu, cena sprzedaży jest ceną minimalną. Do wyprzedaży.
[3] Jeśli nie ma również ceny minimalnej, ustaw cenę sprzedaży jako cenę domyślną „50”.
Wyjaśnij praktyczny przykład z życia.
Widać, że dzięki NVL możemy osiągnąć reguły [1], [2]
Ale dzięki COALSECE możemy osiągnąć wszystkie trzy reguły.
źródło
NVL(Purchase_Price + (Purchase_Price * 0.10), nvl(Min_Price,50))
. Lub około:nvl(NVL(Purchase_Price + (Purchase_Price * 0.10), Min_Price) ,50)
:)