Skip to main content

BEFORE Triggers

BEFORE triggers run prior to row changes.

They are commonly used for validation and guardrails that prevent invalid writes.

Core Concepts

flowchart LR
A[Incoming write] --> B[BEFORE trigger runs]
B --> C{Validation passes?}
C -->|Yes| D[Row change proceeds]
C -->|No| E[Raise error and abort]
Typical useExample
Block invalid valuesDisallow amount <= 0
Enforce custom ruleReject out-of-range status codes

Code Examples

-- Setup table for validation demo.
CREATE TABLE payments_bt (
payment_id INTEGER PRIMARY KEY,
amount REAL NOT NULL
);
Expected output
Table payments_bt created.
-- BEFORE INSERT trigger: reject non-positive amounts.
CREATE TRIGGER trg_payments_before_insert
BEFORE INSERT ON payments_bt
FOR EACH ROW
WHEN NEW.amount <= 0
BEGIN
SELECT RAISE(ABORT, 'amount must be positive');
END;
Expected output
Validation trigger created successfully.
-- Valid insert passes.
INSERT INTO payments_bt (amount)
VALUES (50.0);

-- Invalid insert fails.
INSERT INTO payments_bt (amount)
VALUES (-10.0);
StatementExpected result
Insert 50.0Success
Insert -10.0Error: amount must be positive
-- Verify only valid row exists.
SELECT payment_id, amount
FROM payments_bt;
payment_idamount
150.0

SQLite-Specific Nuances

SQLite Nuance

RAISE() is SQLite-specific trigger control for aborting or failing statements with custom messages.

Common Pitfalls / Best Practices

Pitfall

Using BEFORE triggers for complex transformations that are hard to reason about or test.

Best Practice

Keep BEFORE triggers focused on clear validation rules, and produce actionable error messages.

Quick Challenge

Add a BEFORE UPDATE trigger to block updates where NEW.amount <= 0 in payments_bt.

View Solution
CREATE TRIGGER trg_payments_before_update
BEFORE UPDATE ON payments_bt
FOR EACH ROW
WHEN NEW.amount <= 0
BEGIN
SELECT RAISE(ABORT, 'updated amount must be positive');
END;
Expected output
Trigger created and invalid updates are now blocked.