Friday, March 27, 2026

Oracle SQL MERGE Statement and Advanced DML Patterns — 1Z0-071 Exam Guide

1Z0-071 Exam Prep Chapters 18 & 19 Volume 4

Chapters 18 and 19 cover the more advanced DML patterns on the exam. MERGE is the centrepiece — it combines INSERT and UPDATE into a single statement and the exam tests every clause of its syntax. The other patterns covered here include DEFAULT values in DML, explicit DEFAULT keyword usage, and the behaviour of multi-row DML with constraints.

MERGE questions are not common in high numbers but when they appear, candidates who have not studied the syntax carefully tend to choose plausible-looking wrong answers.

01 — MERGE — the combined INSERT/UPDATE statement

MERGE solves the "upsert" problem — when you have a source of data and you want to update matching rows in a target table and insert rows that don't yet exist, all in one operation. Without MERGE you would need separate UPDATE and INSERT statements with logic to determine which rows need which operation.

-- The problem MERGE solves:
-- You have new employee data in a staging table (emp_updates)
-- For each row: if the employee already exists, UPDATE them
--               if they don't exist yet, INSERT them

-- Without MERGE: two separate statements with subquery logic
UPDATE employees SET salary = ...
WHERE  employee_id IN (SELECT employee_id FROM emp_updates);

INSERT INTO employees ...
SELECT * FROM emp_updates
WHERE  employee_id NOT IN (SELECT employee_id FROM employees);

-- With MERGE: one statement handles both cases cleanly
MERGE is DML: Like INSERT, UPDATE, and DELETE, MERGE is a DML statement. It participates in transactions — it can be rolled back until COMMIT is issued. A DDL statement run after MERGE commits it implicitly, exactly like any other DML.

02 — MERGE full syntax

The MERGE syntax has four key parts: the target table, the source, the join condition, and the WHEN clauses. The exam tests whether each part is in the right place.

MERGE INTO employees e                     -- target table
USING      emp_updates u                    -- source table (or subquery)
ON        (e.employee_id = u.employee_id)   -- join condition
WHEN MATCHED THEN                          -- row exists in target
    UPDATE SET
        e.salary        = u.salary,
        e.department_id = u.department_id
WHEN NOT MATCHED THEN                      -- row does not exist in target
    INSERT (employee_id, last_name, salary, department_id)
    VALUES (u.employee_id, u.last_name, u.salary, u.department_id);
PartKeywordPurpose
TargetMERGE INTOThe table being updated or inserted into
SourceUSINGThe data source — a table, view, or subquery
Join conditionON (...)How to match source rows to target rows
Matched rowsWHEN MATCHED THEN UPDATEWhat to do when source row matches target
Unmatched rowsWHEN NOT MATCHED THEN INSERTWhat to do when source row has no match in target
Cannot UPDATE the join column in WHEN MATCHED: The column used in the ON condition cannot be updated in the WHEN MATCHED UPDATE clause. Since it is the column that identified the match, changing it would create an inconsistency. Oracle raises an error if you try.

03 — MERGE with WHEN NOT MATCHED

WHEN NOT MATCHED fires for every source row that has no matching row in the target table. The INSERT syntax inside WHEN NOT MATCHED follows the same rules as a regular INSERT.

MERGE INTO employees e
USING      new_hires n
ON        (e.employee_id = n.employee_id)
WHEN NOT MATCHED THEN
    INSERT (employee_id, last_name, email, hire_date, job_id, salary)
    VALUES (n.employee_id, n.last_name, n.email,
             n.hire_date, n.job_id, n.salary)
    WHERE  n.hire_date >= TO_DATE('01-JAN-2024', 'DD-MON-YYYY');
-- The optional WHERE on WHEN NOT MATCHED filters which unmatched rows get inserted
-- Source rows that don't match AND don't pass the WHERE are silently skipped
Optional WHERE on WHEN clauses: Both WHEN MATCHED and WHEN NOT MATCHED can have their own WHERE clause. This gives you fine-grained control — you can match on employee_id but only update rows where the source salary is higher, or only insert rows hired after a certain date.

04 — MERGE with WHEN MATCHED — optional DELETE

WHEN MATCHED can include an optional DELETE clause in addition to UPDATE. A row that is matched and updated can also be deleted in the same MERGE operation if it satisfies the DELETE condition.

MERGE INTO employees e
USING      emp_changes c
ON        (e.employee_id = c.employee_id)
WHEN MATCHED THEN
    UPDATE SET e.salary = c.new_salary,
               e.job_id = c.new_job_id
    DELETE WHERE (c.status = 'TERMINATED');
-- Step 1: UPDATE is applied to all matched rows
-- Step 2: Of the rows just updated, those where status = 'TERMINATED' are deleted
-- The DELETE condition is evaluated AFTER the UPDATE, against the updated values
DELETE in MERGE applies to already-updated rows: The DELETE WHERE condition inside WHEN MATCHED is evaluated against the row after the UPDATE has been applied. This means if the UPDATE changes a column that the DELETE condition references, the delete decision uses the new value, not the old one.

05 — Making WHEN clauses optional

Both WHEN MATCHED and WHEN NOT MATCHED are optional in a MERGE statement. You can include just one of them if you only need to handle one case.

-- UPDATE only — no INSERT for new rows
MERGE INTO employees e
USING      salary_updates u
ON        (e.employee_id = u.employee_id)
WHEN MATCHED THEN
    UPDATE SET e.salary = u.new_salary;
-- Unmatched source rows are silently ignored — no INSERT happens

-- INSERT only — no UPDATE for existing rows
MERGE INTO employees e
USING      new_hires n
ON        (e.employee_id = n.employee_id)
WHEN NOT MATCHED THEN
    INSERT (employee_id, last_name, salary)
    VALUES (n.employee_id, n.last_name, n.salary);
-- Matched rows are silently ignored — no UPDATE happens
Clauses presentBehaviour
WHEN MATCHED onlyUpdates matched rows — unmatched source rows ignored
WHEN NOT MATCHED onlyInserts unmatched rows — matched rows ignored
Both clausesUpdates matched, inserts unmatched — full upsert
Neither clauseSyntax error — at least one WHEN clause required

06 — DEFAULT values in INSERT and UPDATE

A DEFAULT value is defined at the column level in CREATE TABLE or ALTER TABLE. It is used automatically when a row is inserted without specifying that column. The exam tests the exact conditions under which Oracle uses the DEFAULT.

-- Column defined with DEFAULT
CREATE TABLE orders (
    order_id    NUMBER        PRIMARY KEY,
    order_date  DATE          DEFAULT SYSDATE,
    status      VARCHAR2(10)  DEFAULT 'PENDING'
);

-- DEFAULT is used when column is omitted from INSERT
INSERT INTO orders (order_id)
VALUES (1001);
-- order_date gets SYSDATE, status gets 'PENDING'

-- DEFAULT is NOT used when NULL is explicitly inserted
INSERT INTO orders (order_id, status)
VALUES (1002, NULL);
-- status gets NULL — not 'PENDING'
-- Explicit NULL overrides the DEFAULT value
Explicit NULL bypasses DEFAULT: When you write VALUES (..., NULL), Oracle stores NULL — it does not fall back to the DEFAULT. The DEFAULT only applies when the column is omitted entirely from the INSERT column list. The exam tests this distinction with questions about what value ends up in the column.

07 — Explicit DEFAULT keyword in DML

Oracle allows you to write the keyword DEFAULT explicitly in INSERT and UPDATE statements to force the default value to be used, even when you are providing values for other columns in the same statement.

-- Using DEFAULT explicitly in INSERT VALUES
INSERT INTO orders (order_id, order_date, status)
VALUES (1003, DEFAULT, 'EXPRESS');
-- order_date gets SYSDATE (the DEFAULT for that column)
-- status gets 'EXPRESS' (explicit value overrides the DEFAULT)

-- Using DEFAULT in UPDATE SET
UPDATE orders
SET    status = DEFAULT
WHERE  order_id = 1003;
-- Resets status to 'PENDING' (its DEFAULT value)
-- Useful when you want to reset a column to its defined default

-- If no DEFAULT is defined, DEFAULT keyword inserts NULL
INSERT INTO employees (employee_id, last_name, commission_pct)
VALUES (400, 'Patel', DEFAULT);
-- commission_pct has no DEFAULT defined — stores NULL

08 — DEFAULT with NULL — important distinction

The exam tests the three-way distinction between: a column having no DEFAULT, a column whose DEFAULT is NULL, and explicitly inserting NULL. These produce the same stored result but have different implications for constraint checking.

ScenarioColumn has DEFAULT 'PENDING'Column has no DEFAULT
Column omitted from INSERTStores 'PENDING'Stores NULL
INSERT ... VALUES (..., NULL)Stores NULL — default ignoredStores NULL
INSERT ... VALUES (..., DEFAULT)Stores 'PENDING'Stores NULL (no default to apply)
UPDATE SET col = DEFAULTSets to 'PENDING'Sets to NULL
DEFAULT in MERGE: The DEFAULT keyword can also be used in MERGE statements — both in the WHEN MATCHED UPDATE SET clause and in the WHEN NOT MATCHED INSERT VALUES clause. The same rules apply.

09 — Multi-row DML and constraint checking

When a DML statement affects multiple rows, Oracle checks constraints after all rows have been processed — not row by row. This is called deferred within a statement and it matters for self-referencing tables.

-- Classic example: swapping manager IDs in a self-referencing table
-- If Oracle checked row by row, intermediate states would violate FK
UPDATE employees
SET    manager_id = CASE
                        WHEN manager_id = 100 THEN 101
                        WHEN manager_id = 101 THEN 100
                    END
WHERE  manager_id IN (100, 101);
-- This works because FK constraints are checked after all rows are updated
-- not after each individual row

-- Constraint violations that affect ALL rows in a statement fail the whole statement
INSERT INTO employees
    SELECT * FROM emp_staging;
-- If even one row violates a constraint, the entire INSERT fails
-- Oracle does not do partial inserts — it's all or nothing per statement
All or nothing per statement: If any row in a multi-row DML statement violates a constraint, the entire statement is rolled back — not just the offending row. A single duplicate in a 1000-row INSERT causes all 1000 rows to be rejected. The exam tests this behaviour specifically.

10 — Quick reference

RuleDetail
MERGE INTO ... USING ... ONTarget, source, join condition — all required
WHEN MATCHED — cannot update join columnRaises error if ON column appears in UPDATE SET
WHEN MATCHED DELETE WHEREDeletes rows after UPDATE — condition uses updated values
Both WHEN clauses are optionalMust have at least one — neither raises error
MERGE is DMLParticipates in transactions — can ROLLBACK
Omitting column uses DEFAULTColumn not in INSERT list gets its DEFAULT value
Explicit NULL overrides DEFAULTVALUES (..., NULL) stores NULL — ignores DEFAULT
DEFAULT keyword in DMLForces the column's defined default — stores NULL if no default exists
Multi-row DML is all or nothingOne constraint violation fails the entire statement
Constraint check timingChecked after all rows processed — not row by row

11 — Practice questions

Q1 — A MERGE statement has a WHEN MATCHED THEN UPDATE SET clause. The ON condition uses employee_id. A developer tries to include e.employee_id = u.employee_id in the UPDATE SET. What happens?
Q2 — A table has a DEFAULT of 'ACTIVE' on the STATUS column. A developer runs:

INSERT INTO orders (order_id, status) VALUES (100, NULL);

What value is stored in STATUS?
Q3 — A developer runs an INSERT that selects 500 rows from a staging table. Row number 347 has a value that violates a UNIQUE constraint on the target table. What is the result?
Oracle SQL 1Z0-071 Exam Prep Guide — Complete 4-Volume Set
19 chapters  ·  1,480 practice questions  ·  1,249 SQL examples
Chapters 18 and 19 cover the full MERGE syntax, DEFAULT behaviour, and advanced DML constraint rules — with practice sets for every pattern. Instant PDF download.
Get the full guide — $25 →

No comments:

Post a Comment