Trigger Design Guidelines
-
Use triggers to ensure that whenever a specific event occurs, any necessary actions are done (regardless of which user or application issues the triggering statement).
For example, use a trigger to ensure that whenever anyone updates a table, its log file is updated.
-
Do not create triggers that duplicate database features.
For example, do not create a trigger to reject invalid data if you can do the same with constraints (see "How Triggers and Constraints Differ").
-
Do not create triggers that depend on the order in which a SQL statement processes rows (which can vary).
For example, do not assign a value to a global package variable in a row trigger if the current value of the variable depends on the row being processed by the row trigger. If a trigger updates global package variables, initialize those variables in a
BEFORE
statement trigger. -
Use
BEFORE
row triggers to modify the row before writing the row data to disk. -
Use
AFTER
row triggers to obtain the row ID and use it in operations.An
AFTER
row trigger fires when the triggering statement results in ORA-02292.Note:
AFTER
row triggers are slightly more efficient thanBEFORE
row triggers. WithBEFORE
row triggers, affected data blocks are read first for the trigger and then for the triggering statement. WithAFTER
row triggers, affected data blocks are read only for the trigger. -
If the triggering statement of a
BEFORE
row trigger is anUPDATE
orDELETE
statement that conflicts with anUPDATE
statement that is running, then the database does a transparentROLLBACK
toSAVEPOINT
and restarts the triggering statement. The database can do this many times before the triggering statement completes successfully. Each time the database restarts the triggering statement, the trigger fires. TheROLLBACK
toSAVEPOINT
does not undo changes to package variables that the trigger references. To ensure that there are no unwanted side effects with each restart, make sure that theBEFORE
row trigger is idempotent, meaning the trigger should be written so that the result remains the same with each subsequent execution. Any additional work that should not be repeated can be handled in anAFTER
row trigger. To detect this situation, you can also include a counter variable in the package. -
Do not create recursive triggers.
For example, do not create an
AFTER
UPDATE
trigger that issues anUPDATE
statement on the table on which the trigger is defined. The trigger fires recursively until it runs out of memory. -
If you create a trigger that includes a statement that accesses a remote database, then put the exception handler for that statement in a stored subprogram and invoke the subprogram from the trigger.
For more information, see "Remote Exception Handling".
-
Use
DATABASE
triggers judiciously. They fire every time any database user initiates a triggering event. -
If a trigger runs the following statement, the statement returns the owner of the trigger, not the user who is updating the table:
SELECT Username FROM USER_USERS;
-
Only committed triggers fire.
A trigger is committed, implicitly, after the
CREATE
TRIGGER
statement that creates it succeeds. Therefore, the following statement cannot fire the trigger that it creates:CREATE OR REPLACE TRIGGER my_trigger AFTER CREATE ON DATABASE BEGIN NULL; END; /
-
To allow the modular installation of applications that have triggers on the same tables, create multiple triggers of the same type, rather than a single trigger that runs a sequence of operations.
Each trigger sees the changes made by the previously fired triggers. Each trigger can see
OLD
andNEW
values.