Conditional Statements (IF/CASE)
PL/SQL provides IF statements and CASE statements (and expressions) to branch execution based on conditions. Both support NULL-aware three-valued logic.
IF / THEN / ELSIF / ELSE / END IF
DECLARE
v_salary employees.salary%TYPE;
v_grade VARCHAR2(10);
BEGIN
SELECT salary INTO v_salary
FROM employees
WHERE employee_id = 107;
IF v_salary >= 15000 THEN
v_grade := 'Senior';
ELSIF v_salary >= 8000 THEN
v_grade := 'Mid';
ELSIF v_salary >= 4000 THEN
v_grade := 'Junior';
ELSE
v_grade := 'Entry';
END IF;
DBMS_OUTPUT.PUT_LINE('Salary: $' || v_salary || ' — Grade: ' || v_grade);
END;
/
Rules:
ELSIF(one word, no space) chains additional conditions.ELSEhandles everything that did not match.- End every
IFblock withEND IF;. - Conditions evaluate left-to-right; the first
TRUEbranch executes, the rest are skipped.
Nested IF Statements
DECLARE
v_dept_id employees.department_id%TYPE := 80;
v_salary employees.salary%TYPE := 12000;
BEGIN
IF v_dept_id = 80 THEN
IF v_salary > 10000 THEN
DBMS_OUTPUT.PUT_LINE('Sales — High performer');
ELSE
DBMS_OUTPUT.PUT_LINE('Sales — Standard');
END IF;
ELSIF v_dept_id = 90 THEN
DBMS_OUTPUT.PUT_LINE('Executive office');
ELSE
DBMS_OUTPUT.PUT_LINE('Other department');
END IF;
END;
/
NULL Semantics in Conditionals
In three-valued logic, NULL comparisons do not yield TRUE or FALSE — they yield NULL, which is treated as FALSE in a condition:
DECLARE
v_bonus NUMBER := NULL;
BEGIN
IF v_bonus > 0 THEN
DBMS_OUTPUT.PUT_LINE('Has bonus'); -- never prints
ELSIF v_bonus = 0 THEN
DBMS_OUTPUT.PUT_LINE('Zero bonus'); -- never prints
ELSE
DBMS_OUTPUT.PUT_LINE('No bonus or NULL'); -- this branch runs
END IF;
-- Correct NULL check
IF v_bonus IS NULL THEN
DBMS_OUTPUT.PUT_LINE('Bonus is NULL');
END IF;
END;
/
Never compare to
NULL using = or != — always use IS NULL or IS NOT NULL. The expression NULL = NULL evaluates to NULL, not TRUE.
Simple CASE Statement
Compares a single selector against a list of values:
DECLARE
v_job_id employees.job_id%TYPE;
v_category VARCHAR2(30);
BEGIN
SELECT job_id INTO v_job_id
FROM employees WHERE employee_id = 100;
CASE v_job_id
WHEN 'AD_PRES' THEN v_category := 'Executive';
WHEN 'AD_VP' THEN v_category := 'Vice President';
WHEN 'IT_PROG' THEN v_category := 'Technical';
WHEN 'SA_REP' THEN v_category := 'Sales';
ELSE v_category := 'Other';
END CASE;
DBMS_OUTPUT.PUT_LINE(v_job_id || ' → ' || v_category);
END;
/
Searched CASE Statement
Evaluates independent Boolean conditions — more flexible than simple CASE:
DECLARE
v_salary NUMBER := 17000;
v_region VARCHAR2(20) := 'EMEA';
v_result VARCHAR2(50);
BEGIN
CASE
WHEN v_salary > 20000 AND v_region = 'US' THEN
v_result := 'US Top Earner';
WHEN v_salary > 15000 THEN
v_result := 'High Earner';
WHEN v_salary BETWEEN 8000 AND 15000 THEN
v_result := 'Mid Earner';
ELSE
v_result := 'Standard';
END CASE;
DBMS_OUTPUT.PUT_LINE(v_result);
END;
/
If no
WHEN matches and there is no ELSE in a CASE statement, Oracle raises CASE_NOT_FOUND (ORA-06592). Always include an ELSE or handle the exception.
CASE Expression vs CASE Statement
A CASE expression returns a value and can appear anywhere a value is expected (assignment, SQL query):
DECLARE
v_salary NUMBER := 12000;
v_grade VARCHAR2(10);
BEGIN
-- CASE expression on the right side of assignment
v_grade := CASE
WHEN v_salary >= 15000 THEN 'Senior'
WHEN v_salary >= 8000 THEN 'Mid'
ELSE 'Junior'
END;
DBMS_OUTPUT.PUT_LINE('Grade: ' || v_grade);
END;
/
CASE expressions can also appear directly in SQL:
SELECT
first_name,
salary,
CASE
WHEN salary >= 15000 THEN 'Senior'
WHEN salary >= 8000 THEN 'Mid'
ELSE 'Junior'
END AS grade
FROM employees
ORDER BY salary DESC;
IF vs simple CASE vs searched CASE — when to use which?
Use IF / ELSIF / ELSE when:
- Conditions involve different variables or complex Boolean expressions.
- Fewer than 3–4 branches (reads naturally).
Use simple CASE when:
- Testing a single variable against a list of discrete values.
- Replaces a chain of
IF var = 'A' / ELSIF var = 'B'.
Use searched CASE when:
- Conditions span multiple variables or use range comparisons.
- You need a value back (use the expression form in an assignment or SQL).
Performance: Oracle compiles both to similar internal bytecode. The readability difference is the main factor.
Real-World Example: Salary Adjustment Logic
CREATE OR REPLACE PROCEDURE adjust_salary(
p_employee_id IN employees.employee_id%TYPE
) IS
v_salary employees.salary%TYPE;
v_job_id employees.job_id%TYPE;
v_increase NUMBER(5,2);
BEGIN
SELECT salary, job_id
INTO v_salary, v_job_id
FROM employees
WHERE employee_id = p_employee_id;
-- Searched CASE for raise percentage
v_increase := CASE
WHEN v_job_id LIKE 'AD_%' THEN 5
WHEN v_job_id LIKE 'SA_%' AND v_salary < 8000 THEN 10
WHEN v_job_id LIKE 'IT_%' THEN 8
ELSE 3
END;
IF v_salary * (1 + v_increase/100) > 25000 THEN
DBMS_OUTPUT.PUT_LINE('Cap reached — no raise for emp ' || p_employee_id);
ELSE
UPDATE employees
SET salary = salary * (1 + v_increase/100)
WHERE employee_id = p_employee_id;
DBMS_OUTPUT.PUT_LINE(
'Emp ' || p_employee_id ||
' raised by ' || v_increase || '%'
);
END IF;
EXCEPTION
WHEN NO_DATA_FOUND THEN
DBMS_OUTPUT.PUT_LINE('Employee ' || p_employee_id || ' not found.');
END adjust_salary;
/
Summary
IF / ELSIF / ELSE / END IFfor general multi-way branching.- Simple
CASEfor a single variable vs. a list of values. - Searched
CASEfor independent conditions — also usable as a value-returning expression. NULLcomparisons always returnNULL(notTRUE/FALSE) — useIS NULL/IS NOT NULL.- A
CASEstatement without anELSEraisesCASE_NOT_FOUNDif noWHENmatches.