Triggers in a DBMS are a set of actions that are automatically executed when an INSERT, UPDATE, or DELETE operation is performed on a specific table.
They follow the Event-Condition-Action (ECA) paradigm: whenever an event E occurs, if a condition C is true, then an action A is executed.
create trigger <TriggerName>
{ before | after }
{ insert | delete | update [ of <Column> ] } on <Table>
[ referencing { [ old table [as] <OldTableAlias> ]
[ new table [as] <NewTableAlias> ] |
[ old [row] [as] <OldTupleName> ]
[ new [row] [as] <NewTupleName> ] } ]
{ for each { row | statement } }
[ when <Condition> ]
<SQLProceduralStatement>
BEFORE triggers allows direct modification of the incoming row (NEW), so the change happens in a single statement. They are ideal for correcting or preventing invalid data and are generally more efficient for “modifying a modification.”
AFTER triggers run after the event completes; to alter data, they must issue a second statement, which is less efficient and sometimes disallowed by the DBMS.
Thus, while both can enforce similar rules, BEFORE triggers are preferred for adjusting values on the go, and AFTER triggers for actions that depend on the committed result.
FOR EACH ROW triggers execute once per affected row and provide access to OLD and NEW values.
FOR EACH STATEMENT triggers execute once per query, regardless of row count. Transition tables can be declared via REFERENCING to access all affected rows.
In short, use row triggers when you need per-row details, and statement triggers when you need table-based behavior. The same logic can often be written either way, but the choice depends on whether the DBMS supports transition tables and whether performance favors per-row or per-statement execution.