Database Triggers (Oracle)

Context: FIT3003_MOC Β· the PL/SQL object the system runs for you Β· the engine of Active Data Warehousing Β· sibling of procedures and functions βž” PL-SQL Stored Procedures and Functions Parent Framework: PL-SQL Stored Procedures and Functions

Quick Revision

  • 🎯 Objective: a self-contained routine attached to a table that runs automatically (β€œfires”) when a row is inserted, updated or deleted βž” never called directly; exam payload = choose timing level event, and read :old / :new correctly.
  • πŸ“¦ Core Components: timing BEFORE / AFTER / INSTEAD OF | level statement (once per DML statement) / row (FOR EACH ROW, once per affected row) | event INSERT / UPDATE [OF col] / DELETE, combinable with OR.
  • ⚑ Key Constraint: :new does not exist for DELETE, and :old is the row being updated or deleted βž” an increment on insert reads :new, a decrement on delete reads :old.

πŸ“ How It Works

1. Trigger vs procedure

  • Who runs it βž” trigger: executed automatically by the system on DML; procedure: called explicitly by a user program.
  • Why use one βž” automatic enforcement of data restrictions (only valid values reach a column) Β· less application maintenance: change the trigger once and every application using the table follows, with no recompile or re-link.

2. Anatomy

CREATE [OR REPLACE] TRIGGER <trigger_name>
  {BEFORE | AFTER | INSTEAD OF}
  {INSERT | UPDATE | DELETE} [OF <column>] ON <table>
  [FOR EACH ROW]
[DECLARE <locals>]
BEGIN
  <trigger body>
END <trigger_name>;
  • Combined events βž” BEFORE INSERT OR UPDATE ON students; column-scoped βž” AFTER … UPDATE OF deptno, sal ON emp fires only when those columns are updated.
  • Level βž” omit FOR EACH ROW βž” statement-level, once per triggering statement; with it βž” row-level, and only row-level triggers see :old / :new.
  • INSTEAD OF βž” defined on a view; the body runs in place of the DML, translating it onto the base tables.
  • Locals βž” a trigger opens them with DECLARE, unlike a procedure.

3. Context variables

Event:old.col:new.col
INSERTno previous rowthe values being inserted
UPDATEthe values before the changethe values after the change
DELETEthe row being deletednot used
  • Before/after comparison βž” :old.deptno != :new.deptno detects an employee changing department.
  • Writing :new βž” a BEFORE row trigger can set a column of the row about to be stored (SELECT seq.nextval INTO :new.ID FROM dual).
  • The colon βž” belongs to :old / :new only; locals are written bare.

4. Event predicates and veto

  • INSERTING / UPDATING / DELETING βž” booleans that branch a multi-event trigger by which DML fired it.
  • RAISE_APPLICATION_ERROR(-20000, 'Cannot perform the operation') βž” shows the message and cancels the triggering operation; placed in a BEFORE trigger it stops the row before it changes.
  • Inspect βž” SELECT trigger_type, table_name, triggering_event FROM user_triggers WHERE trigger_name = 'TOTAL_SALARY';.

βš™οΈ Core Implementation

πŸ”Ή Auto-ID from a sequence

πŸ”Ή Keeping a summary column in step β€” total_salary

πŸ”Ή Making an aggregate view deletable β€” INSTEAD OF

πŸ“Š Exam Execution Trace & Applied Exercises

Manual Execution Trace β€” the four types on one UPDATE

classes_BStatement (BEFORE UPDATE), classes_AStatement (AFTER UPDATE), classes_BRow and classes_ARow (… FOR EACH ROW) each insert (trigger_seq.NEXTVAL, '<their name>') into temp_table. An UPDATE classes … that changes 2 rows logs, in Oracle’s firing order:

num_colchar_colWhy here
Before Statement triggeronce, before any row is touched
Before Row triggerrow 1, before its change
After Row triggerrow 1, after its change
Before Row triggerrow 2
After Row triggerrow 2
After Statement triggeronce, after the last row
  • Count rule βž” affected rows ⟹ log rows; an UPDATE matching no rows still logs the two statement-level lines.

✍️ Practice

⚠️ Common Mistakes

  • πŸ’‘ Statement-level trigger for per-row maintenance βž” without FOR EACH ROW there is no :new, and it fires once whether or rows changed β€” a fact count would move by one per statement.
  • πŸ’‘ πŸ”­ COMMIT inside a trigger (not in the slides) βž” every Chapter 18 trigger ends with commit;, but Oracle rejects it at run time (ORA-04092): a trigger runs inside the transaction of the DML that fired it, so that transaction commits or rolls back as a whole. Exam: follow the slides; live lab: drop the line.
  • πŸ’‘ πŸ”­ Lower-case names in dictionary queries (not in the slides) βž” Oracle stores unquoted names in upper case, so the slides’ WHERE trigger_name = 'total_salary' and name = 'AddNewStudent' return nothing; match 'TOTAL_SALARY', 'ADDNEWSTUDENT'.

🧠 Active Recall