Recently, I attended Kscope15 (see the blog posts in June 2015), an annual convention by Oracle Development Tools User Group.
During one of the sessions by Scott Wesley (Evidence-Based APEX: Building Better Practices), it was explained that COALESCE was better on several fronts than NVL. Since we use NVL quite a bit at IRCS, Inc, I thought I'd compile a post about the subject.
NVL is an Oracle specific command, introduced in the 80s before there were any standards.
COALESCE is a more modern function that is part of the ANSI-92 standard. COALESCE was introduced in Oracle 9i.
NVL (if the first parameter is null, the second parameter is returned, otherwise if the first parameter is any other value other than null, it is returned unchanged):
select NVL(null, 0) from dual; evaluates to 0
select NVL(1, 0) from dual; evaluates to 1
COALESCE (the first non-null value is returned):
select COALESCE(null,0) from dual; evaluates to 0
select COALESCE(1,0) from dual; evaluates to 1
OK, different commands, same answer. In the case of evaluating two values, they are synonyms, except:
1) COALESCE stops evaluation whenever it finds the first non-null.
2) NVL always evaluates both arguments.
So performance wise, COALESCE potentially only has 1/2 the work to do.
However, there is more to COALESCE. COALESCE accepts two or more parameters and returns the first non-null value in a list. If all parameters contain null values, it returns null.
select coalesce(null,null,0) from dual; evaluates to 0 (as it is the first non-null value evaluated).
select coalesce(null,1,2) from dual; evaluates to 1 (as it is the first non-null value evaluated).
select coalesce(null,null,null,null,null,null,1,2,3,4,5) from dual; evaluates to 1 (as it is the first non-null value evaluated).
COALESCE pitfalls:
NVL is tolerant of differing types, for example:
select NVL('Hello',1) from dual; evaluates to 'Hello'
Where
select COALESCE('Hello',1) from dual; evaluates to ORA00932: inconsistent datatypes; expected CHAR got NUMBER....
So be careful in the use of COALESCE. This is specifically true in APEX, where all page items are in reality VARCHAR2. If you are lazy and you are depending on implicit conversion, weird, inconsistent things can happen. Its always best to convert your page items to a known type before you use them.
A good example of the performance difference between NVL and COALESCE is available here
A good description of NULL-related functions available within Oracle is available here