Bird
Raised Fist0
PostgreSQLquery~5 mins

AFTER trigger behavior in PostgreSQL

Choose your learning style10 modes available

Start learning this pattern below

Jump into concepts and practice - no test required

or
Recommended
Test this pattern10 questions across easy, medium, and hard to know if this pattern is strong
Introduction

An AFTER trigger runs after a database action like insert, update, or delete finishes. It helps you do extra work once the main change is done.

You want to log changes after a row is added to a table.
You need to update related tables only after a record is successfully updated.
You want to send notifications after data is deleted.
You want to keep audit trails after data changes.
You want to enforce complex business rules after the main action.
Syntax
PostgreSQL
CREATE TRIGGER trigger_name
AFTER INSERT OR UPDATE OR DELETE ON table_name
FOR EACH ROW
EXECUTE FUNCTION function_name();

AFTER triggers run after the main action completes successfully.

You can define AFTER triggers for INSERT, UPDATE, or DELETE actions.

Examples
This trigger runs after a new employee is added to the employees table.
PostgreSQL
CREATE TRIGGER log_after_insert
AFTER INSERT ON employees
FOR EACH ROW
EXECUTE FUNCTION log_employee_insert();
This trigger runs after an order record is updated.
PostgreSQL
CREATE TRIGGER audit_after_update
AFTER UPDATE ON orders
FOR EACH ROW
EXECUTE FUNCTION audit_order_update();
This trigger runs after a product is deleted.
PostgreSQL
CREATE TRIGGER notify_after_delete
AFTER DELETE ON products
FOR EACH ROW
EXECUTE FUNCTION notify_product_delete();
Sample Program

This example creates two tables: employees and employee_logs. It defines an AFTER INSERT trigger on employees that adds a log entry after a new employee is added. Then it inserts one employee and shows the log.

PostgreSQL
CREATE TABLE employees (
  id SERIAL PRIMARY KEY,
  name TEXT NOT NULL
);

CREATE TABLE employee_logs (
  log_id SERIAL PRIMARY KEY,
  employee_id INT,
  action TEXT,
  log_time TIMESTAMP DEFAULT CURRENT_TIMESTAMP
);

CREATE OR REPLACE FUNCTION log_employee_insert() RETURNS TRIGGER AS $$
BEGIN
  INSERT INTO employee_logs(employee_id, action) VALUES (NEW.id, 'INSERT');
  RETURN NEW;
END;
$$ LANGUAGE plpgsql;

CREATE TRIGGER after_employee_insert
AFTER INSERT ON employees
FOR EACH ROW
EXECUTE FUNCTION log_employee_insert();

INSERT INTO employees(name) VALUES ('Alice');

SELECT * FROM employee_logs;
OutputSuccess
Important Notes

AFTER triggers cannot modify the row being inserted or updated because the main action is already done.

If the AFTER trigger fails, the whole transaction rolls back, so use them carefully.

Summary

AFTER triggers run after the main database action completes successfully.

They are useful for logging, notifications, and related updates.

You define them with CREATE TRIGGER and link to a function that runs after insert, update, or delete.

Practice

(1/5)
1. What is the main purpose of an AFTER trigger in PostgreSQL?
easy
A. To execute a function after the main database operation completes successfully
B. To prevent a database operation from happening
C. To execute a function before the database operation starts
D. To rollback the transaction if an error occurs

Solution

  1. Step 1: Understand the timing of AFTER triggers

    AFTER triggers run only after the main database action (INSERT, UPDATE, DELETE) has completed successfully.
  2. Step 2: Identify the purpose of AFTER triggers

    They are used to perform actions like logging or notifications after the main operation finishes.
  3. Final Answer:

    To execute a function after the main database operation completes successfully -> Option A
  4. Quick Check:

    AFTER trigger = runs after operation [OK]
Hint: AFTER triggers run only after successful main actions [OK]
Common Mistakes:
  • Confusing AFTER with BEFORE triggers
  • Thinking AFTER triggers can stop the main operation
  • Assuming AFTER triggers run before the operation
2. Which of the following is the correct syntax to create an AFTER INSERT trigger in PostgreSQL?
easy
A. CREATE TRIGGER trg AFTER INSERT ON table_name FOR EACH ROW EXECUTE FUNCTION func_name();
B. CREATE TRIGGER trg AFTER INSERT ON table_name EXECUTE FUNCTION func_name();
C. CREATE TRIGGER trg BEFORE INSERT ON table_name EXECUTE FUNCTION func_name();
D. CREATE TRIGGER trg AFTER INSERT ON table_name FOR EACH STATEMENT EXECUTE FUNCTION func_name();

Solution

  1. Step 1: Recall the correct CREATE TRIGGER syntax

    PostgreSQL requires specifying FOR EACH ROW or FOR EACH STATEMENT for triggers.
  2. Step 2: Identify the correct syntax for AFTER INSERT

    CREATE TRIGGER trg AFTER INSERT ON table_name FOR EACH ROW EXECUTE FUNCTION func_name(); correctly uses AFTER INSERT ON table_name FOR EACH ROW EXECUTE FUNCTION func_name();
  3. Final Answer:

    CREATE TRIGGER trg AFTER INSERT ON table_name FOR EACH ROW EXECUTE FUNCTION func_name(); -> Option A
  4. Quick Check:

    AFTER INSERT + FOR EACH ROW + EXECUTE FUNCTION = CREATE TRIGGER trg AFTER INSERT ON table_name FOR EACH ROW EXECUTE FUNCTION func_name(); [OK]
Hint: AFTER triggers need FOR EACH ROW or STATEMENT [OK]
Common Mistakes:
  • Omitting FOR EACH ROW or FOR EACH STATEMENT
  • Using BEFORE instead of AFTER
  • Using EXECUTE PROCEDURE instead of EXECUTE FUNCTION in modern PostgreSQL
3. Given the following trigger and table, what will be the output after inserting a row?
CREATE TABLE users(id SERIAL PRIMARY KEY, name TEXT);
CREATE FUNCTION log_insert() RETURNS trigger AS $$
BEGIN
  RAISE NOTICE 'Inserted user: %', NEW.name;
  RETURN NEW;
END;
$$ LANGUAGE plpgsql;
CREATE TRIGGER after_user_insert AFTER INSERT ON users FOR EACH ROW EXECUTE FUNCTION log_insert();

INSERT INTO users(name) VALUES ('Alice');
medium
A. No output, the insert happens silently
B. An error occurs because RETURN NEW is invalid in AFTER trigger
C. The insert is rolled back due to the trigger
D. A notice message: 'Inserted user: Alice'

Solution

  1. Step 1: Understand the trigger function behavior

    The function raises a NOTICE with the inserted user's name after insert.
  2. Step 2: Recognize AFTER trigger effects

    AFTER triggers run after the insert, so the notice will be shown, and the insert completes successfully.
  3. Final Answer:

    A notice message: 'Inserted user: Alice' -> Option D
  4. Quick Check:

    AFTER trigger raises notice = A notice message: 'Inserted user: Alice' [OK]
Hint: AFTER triggers can raise notices after insert [OK]
Common Mistakes:
  • Thinking RETURN NEW is invalid in AFTER triggers
  • Expecting no output from the trigger
  • Assuming the insert is rolled back
4. You created an AFTER UPDATE trigger but it never fires. Which of the following is the most likely cause?
medium
A. The trigger was created as BEFORE UPDATE instead of AFTER UPDATE
B. The UPDATE statement does not change any column values
C. The trigger function does not return NEW or OLD
D. The trigger is defined FOR EACH STATEMENT but the function expects FOR EACH ROW

Solution

  1. Step 1: Understand when AFTER UPDATE triggers fire

    AFTER UPDATE triggers fire only if the UPDATE actually changes data.
  2. Step 2: Analyze the cause of no trigger firing

    If the UPDATE sets columns to their existing values, no actual change occurs, so the trigger does not fire.
  3. Final Answer:

    The UPDATE statement does not change any column values -> Option B
  4. Quick Check:

    UPDATE with no change = no AFTER trigger fire [OK]
Hint: AFTER UPDATE triggers fire only on actual data changes [OK]
Common Mistakes:
  • Assuming triggers fire even if no data changes
  • Confusing BEFORE and AFTER triggers
  • Not matching trigger function with trigger type
5. You want to log every DELETE on a table after it happens, but only if the deleted row's status is 'active'. Which is the best way to implement this using an AFTER trigger?
hard
A. Create an AFTER DELETE trigger that logs all deletes without checking status
B. Create a BEFORE DELETE trigger that checks OLD.status and prevents deletion if not 'active'
C. Create an AFTER DELETE trigger that checks if OLD.status = 'active' inside the trigger function before logging
D. Create a BEFORE DELETE trigger that logs only if OLD.status = 'active'

Solution

  1. Step 1: Understand the requirement for conditional logging after delete

    We want to log only after the delete happens and only for rows with status 'active'.
  2. Step 2: Choose the correct trigger timing and condition

    AFTER DELETE trigger can access OLD row data and conditionally log if OLD.status = 'active'.
  3. Final Answer:

    Create an AFTER DELETE trigger that checks if OLD.status = 'active' inside the trigger function before logging -> Option C
  4. Quick Check:

    Conditional logging after delete = AFTER trigger with check [OK]
Hint: Use AFTER DELETE trigger with condition inside function [OK]
Common Mistakes:
  • Using BEFORE trigger which runs before deletion
  • Logging all deletes without condition
  • Trying to prevent deletion instead of logging