Есть ли неочевидные различия между NVL и Coalesce в Oracle?
Очевидные различия заключаются в том, что coalesce вернет первый ненулевой элемент в своем списке параметров, тогда как nvl принимает только два параметра и возвращает первый, если он не нулевой, в противном случае он возвращает второй.
Кажется, что NVL может быть просто «базовым» вариантом объединения.
Я что-то упускаю?
Ответы:
COALESCE
это более современная функция, которая является частьюANSI-92
стандарта.NVL
являетсяOracle
конкретным, он был введен в80
«с до появления каких - либо стандартов.В случае двух значений они являются синонимами.
Однако они реализованы по-разному.
NVL
всегда оценивает оба аргумента, в то время какCOALESCE
обычно останавливает оценку всякий раз, когда находит первый неNULL
(есть некоторые исключения, такие как последовательностьNEXTVAL
):Это выполняется в течение почти
0.5
секунд, так как он генерируетSYS_GUID()
s, хотя1
и не являетсяNULL
.Это понимает, что
1
не являетсяNULL
и не оценивает второй аргумент.SYS_GUID
не генерируются и запрос мгновенный.источник
NVL выполнит неявное преобразование в тип данных первого параметра, поэтому следующее не приводит к ошибке
COALESCE ожидает согласованных типов данных.
выдаст «непоследовательную ошибку типа данных»
источник
NVL и COALESCE используются для достижения одинаковой функциональности предоставления значения по умолчанию в случае, если столбец возвращает NULL.
Различия:
Примеры для третьего случая. Другие случаи просты.
select nvl('abc',10) from dual;
будет работать, так как NVL будет выполнять неявное преобразование числа 10 в строку.select coalesce('abc',10) from dual;
потерпит неудачу с ошибкой - несовместимые типы данных: ожидаемый CHAR получил NUMBERПример использования UNION
не удается с
ORA-00932: inconsistent datatypes: expected CHAR got DATE
преуспевает.
Дополнительная информация: http://www.plsqlinformation.com/2016/04/difference-between-nvl-and-coalesce-in-oracle.html
источник
Существует также разница в обработке плана.
Oracle может формировать оптимизированный план с конкатенацией фильтров ветвлений, когда поиск содержит сравнение
nvl
результатов с индексированным столбцом.NVL:
COALESCE:
Кредиты перейдите по адресу http://www.xt-r.com/2012/03/nvl-coalesce-concatenation.html .
источник
Еще одно доказательство того, что coalesce () не останавливает вычисление с первым ненулевым значением:
Запустите это, затем проверьте
my_sequence.currval;
источник
На самом деле я не могу согласиться с каждым утверждением.
«COALESCE ожидает, что все аргументы будут одного типа».
Это неправильно, см. Ниже. Аргументы могут быть разных типов данных, что также задокументировано : если все вхождения expr являются числовым типом данных или любым нечисловым типом данных, который может быть неявно преобразован в числовой тип данных, то Oracle Database определяет аргумент с наивысшим числовым приоритетом, неявно преобразует оставшиеся аргументы в этот тип данных и возвращает этот тип данных. , На самом деле это даже противоречит общему выражению «COALESCE останавливается при первом появлении ненулевого значения», в противном случае контрольный пример № 4 не должен вызывать ошибку.
Также согласно тесту № 5
COALESCE
выполняется неявное преобразование аргументов.источник
Хотя это очевидно, и даже упомянуто в том виде, в каком он был поставлен Томом, который задал этот вопрос. Но давайте снова смиримся.
NVL может иметь только 2 аргумента. Коалесция может иметь более 2.
select nvl('','',1) from dual;
// Результат::ORA-00909
неверное количество аргументовselect coalesce('','','1') from dual;
// Вывод: возвращает 1источник
NVL: заменить ноль на значение.
COALESCE: вернуть первое ненулевое выражение из списка выражений.
Таблица: PRICE_LIST
Ниже приведен пример
[1] Установить цену продажи с добавлением 10% прибыли ко всем продуктам.
[2] Если нет цены по прейскуранту, тогда минимальная цена продажи. Для распродажи.
[3] Если также нет минимальной цены, установите цену продажи по умолчанию "50".
Объясните на практике реальный пример.
Вы можете видеть, что с NVL мы можем достичь правил [1], [2]
Но с COALSECE мы можем выполнить все три правила.
источник
NVL(Purchase_Price + (Purchase_Price * 0.10), nvl(Min_Price,50))
. Или о:nvl(NVL(Purchase_Price + (Purchase_Price * 0.10), Min_Price) ,50)
:)