5.3 General NULL-Handling Functions
Key Takeaways
- NVL(expr1, expr2) replaces a NULL expr1 with expr2; if datatypes differ, Oracle implicitly converts expr2 to match expr1's datatype.
- NVL2(expr1, expr2, expr3) returns expr2 if expr1 is NOT NULL, and expr3 if expr1 is NULL; the return datatype is always determined by expr2.
- NULLIF(expr1, expr2) compares two expressions and returns NULL if they are equal, or expr1 if they differ; expr1 cannot be a literal NULL.
- COALESCE(expr1, expr2, ..., exprn) returns the first non-null expression in its argument list and utilizes short-circuit (lazy) evaluation.
- COALESCE is an ANSI SQL standard function, whereas NVL and NVL2 are Oracle proprietary; all expressions in COALESCE must share a compatible datatype with the first expression.
5.3 General NULL-Handling Functions
In relational database theory and Oracle SQL, NULL represents a state of missing, unknown, unassigned, or inapplicable data. Because NULL does not represent a known value, standard arithmetic operations and comparison operators exhibit distinct three-valued logic ($TRUE$, $FALSE$, $UNKNOWN$):
- Any arithmetic operation involving
NULLyieldsNULL(e.g.,salary + commission_pctyieldsNULLif commission is null). - Standard equality comparisons against
NULLyieldUNKNOWNrather thanTRUE(e.g.,commission_pct = NULLnever matches any row).
To manage null values safely in calculations, reports, and logical predicates, Oracle SQL provides four general NULL-handling functions: NVL, NVL2, NULLIF, and COALESCE.
1. The NVL Function
The NVL(expr1, expr2) function replaces a NULL value with a meaningful alternate value.
+------------------------+
| NVL(expr1, expr2) |
+------------------------+
|
+----------------+----------------+
| |
[expr1 IS NOT NULL] [expr1 IS NULL]
| |
v v
Returns: expr1 Returns: expr2
Syntax & Datatype Rules:
NVL(expr1, expr2)
- If
expr1is NOT NULL,NVLreturnsexpr1. - If
expr1is NULL,NVLreturnsexpr2. - Datatype Compatibility Rule: The datatypes of
expr1andexpr2must be compatible. If they differ, Oracle implicitly convertsexpr2to the datatype ofexpr1before returning a value.
-- Calculating total compensation (replacing NULL commission with 0):
SELECT employee_id,
salary + (salary * NVL(commission_pct, 0)) AS total_compensation
FROM employees;
-- Datatype coercion example: '100' is implicitly converted to NUMBER (datatype of expr1):
SELECT NVL(100, '200') FROM dual; --> Returns 100 (NUMBER)
-- Datatype mismatch error: Oracle tries to convert 'None' to NUMBER and fails:
SELECT NVL(commission_pct, 'None') FROM employees;
-- Error: ORA-01722: invalid number
-- Correct approach with explicit conversion:
SELECT NVL(TO_CHAR(commission_pct), 'None') FROM employees;
Exam Watchout:
NVLdoes not short-circuit. Bothexpr1andexpr2are always evaluated by the SQL engine, even whenexpr1is not null.
2. The NVL2 Function
The NVL2(expr1, expr2, expr3) function provides three-parameter conditional substitution based on whether the first expression is null or not null.
+------------------------------+
| NVL2(expr1, expr2, expr3) |
+------------------------------+
|
+----------------+----------------+
| |
[expr1 IS NOT NULL] [expr1 IS NULL]
| |
v v
Returns: expr2 Returns: expr3
Syntax & Datatype Rules:
NVL2(expr1, expr2, expr3)
- If
expr1is NOT NULL,NVL2returnsexpr2. - If
expr1is NULL,NVL2returnsexpr3. - Datatype Rule:
expr1can be of any datatype. The return datatype of the function is determined byexpr2:- If
expr2is numeric,expr3is converted to numeric. - If
expr2is character data,expr3is converted to character (VARCHAR2).
- If
-- Displaying compensation status:
SELECT last_name,
salary,
NVL2(commission_pct, 'Salary + Comm', 'Salary Only') AS income_type,
NVL2(commission_pct, salary + (salary * commission_pct), salary) AS net_pay
FROM employees;
Exam Trap: In
NVL2, the second parameter (expr2) corresponds to the NOT NULL state, and the third parameter (expr3) corresponds to the NULL state. Do not invert the arguments!
3. The NULLIF Function
The NULLIF(expr1, expr2) function compares two expressions and returns NULL if they are equal, or expr1 if they are not equal.
+------------------------+
| NULLIF(expr1, expr2) |
+------------------------+
|
+----------------+----------------+
| |
[expr1 = expr2] [expr1 != expr2]
| |
v v
Returns: NULL Returns: expr1
Syntax & Critical Restrictions:
NULLIF(expr1, expr2)
- If
expr1equalsexpr2,NULLIFreturnsNULL. - If
expr1does not equalexpr2,NULLIFreturnsexpr1. - The Literal NULL Restriction: The first argument
expr1CANNOT be the literal keywordNULL. WritingNULLIF(NULL, expr2)causes an immediate syntax error (ORA-00932: inconsistent datatypesorORA-00904). expr1andexpr2must be of comparable datatypes.
Practical Applications of NULLIF:
-
Preventing Division-by-Zero Errors (
ORA-01476):SELECT department_id, total_sales / NULLIF(staff_count, 0) AS sales_per_rep FROM department_stats;If
staff_countis0,NULLIF(staff_count, 0)returnsNULL, andtotal_sales / NULLsafely yieldsNULLinstead of crashing the query with a division-by-zero error. -
Cleansing Sentinel / Default Values:
-- Converting dummy text 'N/A' into true NULL: SELECT customer_id, NULLIF(phone_number, 'N/A') AS clean_phone FROM customers;
4. The COALESCE Function
The COALESCE(expr1, expr2, ..., exprn) function evaluates a list of expressions from left to right and returns the first non-null expression encountered.
+-------------------------------------------------------------------------+
| COALESCE(expr1, expr2, expr3, ..., exprN) |
+-------------------------------------------------------------------------+
| Evaluate expr1 -> NOT NULL? ------> RETURN expr1 |
| | (is NULL) |
| v |
| Evaluate expr2 -> NOT NULL? ------> RETURN expr2 |
| | (is NULL) |
| v |
| Evaluate expr3 -> NOT NULL? ------> RETURN expr3 |
| | (is NULL) |
| v |
| ... All NULL? --------------------> RETURN NULL |
+-------------------------------------------------------------------------+
Syntax & Characteristics:
COALESCE(expr1, expr2, ..., exprn)
- Requires at least two arguments.
- Returns the value of the first expression that does not evaluate to
NULL. - If all arguments evaluate to
NULL,COALESCEreturnsNULL. - Short-Circuit (Lazy) Evaluation:
COALESCEstops evaluating expressions as soon as a non-null value is found. Expressions appearing after the first non-null argument are never executed, offering performance savings and error prevention. - Datatype Consistency: All expressions in the parameter list must share a compatible datatype with the first expression (
expr1).
-- Cascading contact lookup:
SELECT customer_id,
COALESCE(mobile_phone, business_phone, home_phone, 'No Contact Available') AS contact_info
FROM customer_contacts;
Comprehensive NULL-Handling Functions Comparison
| Feature | NVL | NVL2 | NULLIF | COALESCE |
|---|---|---|---|---|
| Number of Arguments | Exactly 2 | Exactly 3 | Exactly 2 | 2 or more ($N \ge 2$) |
| Logic | Returns expr2 if expr1 is NULL | Returns expr2 if expr1 NOT NULL; expr3 if NULL | Returns NULL if expr1 = expr2; else expr1 | Returns first non-null expression |
| Return Datatype Rule | Datatype of expr1 | Datatype of expr2 | Datatype of expr1 | Datatype of expr1 |
| Short-Circuit Evaluation? | No (evaluates both) | No (evaluates all) | No | Yes (stops at first non-null) |
| Standard Compliance | Oracle Proprietary | Oracle Proprietary | ANSI SQL Standard | ANSI SQL Standard |
| Key Syntax Restriction | Types must be compatible | Types of expr2/3 must match | expr1 cannot be literal NULL | All types must match expr1 |
Examine the following SQL statement executed on the EMPLOYEES table: SELECT last_name, NVL2(commission_pct, salary * (1 + commission_pct), salary + 500) AS calc_pay FROM employees WHERE employee_id = 105; Suppose employee 105 has SALARY = 10000 and COMMISSION_PCT = 0.20. What value is returned for CALC_PAY?
Which of the following SQL statements will fail to compile and raise an Oracle syntax error?
What is the primary operational difference between the NVL and COALESCE functions in Oracle SQL regarding expression evaluation?