|Oracle9i Database Concepts
Release 2 (9.2)
Part Number A96524-01
This chapter discusses triggers, which are procedures written in PL/SQL, Java, or C that run (fire) implicitly whenever a table or view is modified or when some user actions or database system actions occur. You can write triggers that fire whenever one of the following operations occurs: DML statements on a particular schema object, DDL statements issued within a schema or database, user logon or logoff events, server errors, database startup, or instance shutdown.
This chapter includes:
Oracle lets you define procedures called triggers that run implicitly when an
DELETE statement is issued against the associated table or, in some cases, against a view, or when database system actions occur. These procedures can be written in PL/SQL or Java and stored in the database, or they can be written as C callouts.
Triggers are similar to stored procedures. A trigger stored in the database can include SQL and PL/SQL or Java statements to run as a unit and can invoke stored procedures. However, procedures and triggers differ in the way that they are invoked. A procedure is explicitly run by a user, application, or trigger. Triggers are implicitly fired by Oracle when a triggering event occurs, no matter which user is connected or which application is being used.
Figure 17-1 shows a database application with some SQL statements that implicitly fire several triggers stored in the database. Notice that the database stores triggers separately from their associated tables.
A trigger can also call out to a C procedure, which is useful for computationally intensive operations.
The events that fire a trigger include the following:
Oracle Forms can define, store, and run triggers of a different sort. However, do not confuse Oracle Forms triggers with the triggers discussed in this chapter.
Triggers supplement the standard capabilities of Oracle to provide a highly customized database management system. For example, a trigger can restrict DML operations against a table to those issued during regular business hours. You can also use triggers to:
Oracle9i Application Developer's Guide - Fundamentals for examples of trigger uses
Although triggers are useful for customizing a database, use them only when necessary. Excessive use of triggers can result in complex interdependencies, which can be difficult to maintain in a large application. For example, when a trigger fires, a SQL statement within its trigger action potentially can fire other triggers, resulting in cascading triggers. This can produce unintended effects. Figure 17-2 illustrates cascading triggers.
You can use both triggers and integrity constraints to define and enforce any type of integrity rule. However, Oracle Corporation strongly recommends that you use triggers to constrain data input only in the following situations:
"How Oracle Enforces Data Integrity" for more information about integrity constraints
A trigger has three basic parts:
Figure 17-3 represents each of these parts of a trigger and is not meant to show exact syntax. The sections that follow explain each part of a trigger in greater detail.
A triggering event or statement is the SQL statement, database event, or user event that causes a trigger to fire. A triggering event can be one or more of the following:
DELETEstatement on a specific table (or view, in some cases)
DROPstatement on any schema object
For example, in Figure 17-3, the triggering statement is:
This statement means that when the
parts_on_hand column of a row in the
inventory table is updated, fire the trigger. When the triggering event is an
UPDATE statement, you can include a column list to identify which columns must be updated to fire the trigger. You cannot specify a column list for
DELETE statements, because they affect entire rows of information.
A triggering event can specify multiple SQL statements:
This part means that when an
DELETE statement is issued against the
inventory table, fire the trigger. When multiple types of SQL statements can fire a trigger, you can use conditional predicates to detect the type of triggering statement. In this way, you can create a single trigger that runs different code based on the type of statement that fires the trigger.
A trigger restriction specifies a Boolean expression that must be
true for the trigger to fire. The trigger action is not run if the trigger restriction evaluates to
unknown. In the example, the trigger restriction is:
Consequently, the trigger does not fire unless the number of available parts is less than a present reorder amount.
A trigger action is the procedure (PL/SQL block, Java program, or C callout) that contains the SQL statements and code to be run when the following events occur:
Like stored procedures, a trigger action can:
If the triggers are row triggers, the statements in a trigger action have access to column values of the row being processed by the trigger. Correlation names provide access to the old and new values for each column.
This section describes the different types of triggers:
When you define a trigger, you can specify the number of times the trigger action is to be run:
UPDATEstatement that updates many rows
A row trigger is fired each time the table is affected by the triggering statement. For example, if an
UPDATE statement updates multiple rows of a table, a row trigger is fired once for each row affected by the
UPDATE statement. If a triggering statement affects no rows, a row trigger is not run.
Row triggers are useful if the code in the trigger action depends on data provided by the triggering statement or rows that are affected. For example, Figure 17-3 illustrates a row trigger that uses the values of each row affected by the triggering statement.
A statement trigger is fired once on behalf of the triggering statement, regardless of the number of rows in the table that the triggering statement affects, even if no rows are affected. For example, if a
DELETE statement deletes several rows from a table, a statement-level
DELETE trigger is fired only once.
Statement triggers are useful if the code in the trigger action does not depend on the data provided by the triggering statement or the rows affected. For example, use a statement trigger to:
When defining a trigger, you can specify the trigger timing--whether the trigger action is to be run before or after the triggering statement.
AFTER apply to both statement and row triggers.
AFTER triggers fired by DML statements can be defined only on tables, not on views. However, triggers on the base tables of a view are fired if an
DELETE statement is issued against the view.
AFTER triggers fired by DDL statements can be defined only on the database or a schema, not on particular tables.
BEFORE triggers run the trigger action before the triggering statement is run. This type of trigger is commonly used in the following situations:
BEFOREtrigger for this purpose, you can eliminate unnecessary processing of the triggering statement and its eventual rollback in cases where an exception is raised in the trigger action.
AFTER triggers run the trigger action after the triggering statement is run.
Using the options listed previously, you can create four types of row and statement triggers:
Before executing the triggering statement, the trigger action is run.
Before modifying each row affected by the triggering statement and before checking appropriate integrity constraints, the trigger action is run, if the trigger restriction was not violated.
After modifying each row affected by the triggering statement and possibly applying appropriate integrity constraints, the trigger action is run for the current row provided the trigger restriction was not violated. Unlike
row triggers lock rows.
After executing the triggering statement and applying any deferred integrity constraints, the trigger action is run.
You can have multiple triggers of the same type for the same statement for any given table. For example, you can have two
statement triggers for
UPDATE statements on the
employees table. Multiple triggers of the same type permit modular installation of applications that have triggers on the same tables. Also, Oracle materialized view logs use
row triggers, so you can design your own
row trigger in addition to the Oracle-defined
You can create as many triggers of the preceding different types as you need for each type of DML statement, (
For example, suppose you have a table,
SAL, and you want to know when the table is being accessed and the types of queries being issued. The following example contains a sample package and trigger that tracks this information by hour and type of action (for example,
INSERT) on table
SAL. The global session variable
ROWCNT is initialized to zero by a
statement trigger. Then it is increased each time the row trigger is run. Finally the statistical information is saved in the table
STAT_TAB by the
Oracle9i Application Developer's Guide - Fundamentals for examples of trigger applications
OF triggers provide a transparent way of modifying views that cannot be modified directly through DML statements (
DELETE). These triggers are called
OF triggers because, unlike other types of triggers, Oracle fires the trigger instead of executing the triggering statement.
You can write normal
DELETE statements against the view and the
OF trigger is fired to update the underlying tables appropriately.
OF triggers are activated for each row of the view that gets modified.
Modifying views can have ambiguous results:
Object views present additional problems. For example, a key use of object views is to represent master/detail relationships. This operation inevitably involves joins, but modifying joins is inherently ambiguous.
As a result of these ambiguities, there are many restrictions on which views are modifiable. An
OF trigger can be used on object views as well as relational views that are not otherwise modifiable.
Even if the view is inherently modifiable, you might want to perform validations on the values being inserted, updated or deleted.
OF triggers can also be used in this case. Here the trigger code performs the validation on the rows being modified and if valid, propagate the changes to the underlying tables.
OF triggers also enable you to modify object view instances on the client-side through OCI. To modify an object materialized by an object view in the client-side object cache and flush it back to the persistent store, you must specify
OF triggers, unless the object view is inherently modifiable. However, it is not necessary to define these triggers for just pinning and reading the view object in the object cache.
A view is inherently modifiable if data can be inserted, updated, or deleted without using
OF triggers and if it conforms to the restrictions listed as follows. If the view query contains any of the following constructs, the view is not inherently modifiable and you therefore cannot perform inserts, updates, or deletes on the view:
If a view contains pseudocolumns or expressions, you can only update the view with an
UPDATE statement that does not refer to any of the pseudocolumns or expressions.
You cannot modify the elements of a nested table column in a view directly with the
TABLE clause. However, you can do so by defining an
OF trigger on the nested table column of the view. The triggers on the nested tables fire if a nested table element is updated, inserted, or deleted and handle the actual modifications to the underlying tables.
You can use triggers to publish information about database events to subscribers. Applications can subscribe to database events just as they subscribe to messages from other applications. These database events can include:
Triggers on system events can be defined at the database level or schema level. For example, a database shutdown trigger is defined at the database level:
Triggers on DDL statements or logon/logoff events can also be defined at the database level or schema level. Triggers on DML statements can be defined on a table or view. A trigger defined at the database level fires for all users, and a trigger defined at the schema or table level fires only when the triggering event involves that schema or table.
Event publication uses the publish-subscribe mechanism of Oracle Advanced Queuing. A queue serves as a message repository for subjects of interest to various subscribers. Triggers use the
DBMS_AQ package to enqueue a message when specific system or user events occur.
Each event allows the use of attributes within the trigger text. For example, the database startup and shutdown triggers have attributes for the instance number and the database name, and the logon and logoff triggers have attributes for the username. You can specify a function with the same name as an attribute when you create a trigger if you want to publish that attribute when the event occurs. The attribute's value is then passed to the function or payload when the trigger fires. For triggers on DML statements, the
:OLD column values pass the attribute's value to the
:NEW column value.
System events that can fire triggers are related to instance startup and shutdown and error messages. Triggers created on startup and shutdown events have to be associated with the database. Triggers created on error events can be associated with the database or with a schema.
STARTUPtriggers fire when the database is opened by an instance. Their attributes include the system event, instance number, and database name.
SHUTDOWNtriggers fire just before the server starts shutting down an instance. You can use these triggers to make subscribing applications shut down completely when the database shuts down. For abnormal instance shutdown, these triggers cannot be fired. The attributes of
SHUTDOWNtriggers include the system event, instance number, and database name.
SERVERERRORtriggers fire when a specified error occurs, or when any error occurs if no error number is specified. Their attributes include the system event and error number.
User events that can fire triggers are related to user logon and logoff, DDL statements, and DML statements.
LOGOFF triggers can be associated with the database or with a schema. Their attributes include the system event and username, and they can specify simple conditions on
LOGONtriggers fire after a successful logon of a user.
LOGOFFtriggers fire at the start of a user logoff.
DDL triggers can be associated with the database or with a schema. Their attributes include the system event, the type of schema object, and its name. They can specify simple conditions on the type and name of the schema object, as well as functions like
USERNAME. DDL triggers include the following types of triggers:
CREATEtriggers fire when a schema object is created in the database or schema.
ALTERtriggers fire when a schema object is altered in the database or schema.
DROPtriggers fire when a schema object is dropped from the database or schema.
DML triggers for event publication are associated with a table. They can be either
AFTER triggers that fire for each row on which the specified DML operation occurs. You cannot use
OF triggers on views to publish events related to DML statements--instead, you can publish events using
AFTER triggers for the DML operations on a view's underlying tables that are caused by
The attributes of DML triggers for event publication include the system event and the columns defined by the user in the
SELECT list. They can specify simple conditions on the type and name of the schema object, as well as functions (such as
SYSDATE), pseudocolumns, and columns. The columns can be prefixed by
:NEW for old and new values. Triggers on DML statements include the following triggers:
INSERTtriggers fire for each row inserted into the table.
UPDATEtriggers fire for each row updated in the table.
DELETEtriggers fire for each row deleted from the table.
A trigger is in either of two distinct modes:
An enabled trigger runs its trigger action if a triggering statement is issued and the trigger restriction (if any) evaluates to
A disabled trigger does not run its trigger action, even if a triggering statement is issued and the trigger restriction (if any) would evaluate to
For enabled triggers, Oracle automatically performs the following actions:
A single SQL statement can potentially fire up to four types of triggers:
A triggering statement or a statement within a trigger can cause one or more integrity constraints to be checked. Also, triggers can contain statements that cause other triggers to fire (cascading triggers).
Oracle uses the following execution model to maintain the proper firing sequence of multiple triggers and constraint checking:
statementtriggers that apply to the statement.
statementtriggers that apply to the statement.
The definition of the execution model is recursive. For example, a given SQL statement can cause a
row trigger to be fired and an integrity constraint to be checked. That
row trigger, in turn, might perform an update that causes an integrity constraint to be checked and an
statement trigger to be fired. The
statement trigger causes an integrity constraint to be checked. In this case, the execution model runs the steps recursively, as follows:
Original SQL statement issued.
statementtriggers fired by
i. Statements of
statement triggers run.
ii. Integrity constraint checked on tables changed by
There are two exceptions to this recursion:
NULLare fired before and after the user
DELETEstatement, not before and after the individual enforcement statements. This prevents those statement triggers from encountering mutating errors.
An important property of the execution model is that all actions and checks done as a result of a SQL statement must succeed. If an exception is raised within a trigger, and the exception is not explicitly handled, all actions performed as a result of the original SQL statement, including the actions performed by fired triggers, are rolled back. Thus, integrity constraints cannot be compromised by triggers. The execution model takes into account integrity constraints and disallows triggers that violate declarative integrity constraints.
For example, in the previously outlined scenario, suppose that Steps 1 through 8 succeed; however, in Step 9 the integrity constraint is violated. As a result of this violation, all changes made by the SQL statement (in Step 8), the fired
row trigger (in Step 6), and the fired
statement trigger (in Step 4) are rolled back.
Although triggers of different types are fired in a specific order, triggers of the same type for the same statement are not guaranteed to fire in any specific order. For example, all
When a trigger is fired, the tables referenced in the trigger action might be currently undergoing changes by SQL statements in other users' transactions. In all cases, the SQL statements run within triggers follow the common rules used for standalone SQL statements. In particular, if an uncommitted transaction has modified values that a trigger being fired either needs to read (query) or write (update), then the SQL statements in the body of the trigger being fired use the following guidelines:
The following examples illustrate these points.
Assume that the
salary_check trigger (body) includes the following
SELECT min_salary, max_salary INTO min_salary, max_salary FROM jobs WHERE job_title = :new.job_title;
For this example, assume that transaction T1 includes an update to the
max_salary column of the
jobs table. At this point, the
salary_check trigger is fired by a statement in transaction
SELECT statement within the fired trigger (originating from
T2) does not see the update by the uncommitted transaction
T1, and the query in the trigger returns the old
max_salary value as of the read-consistent point for transaction
Assume that the
total_salary trigger maintains a derived column that stores the total salary of all members in a department:
CREATE TRIGGER total_salary AFTER DELETE OR INSERT OR UPDATE OF department_id, salary ON employees FOR EACH ROW BEGIN /* assume that department_id and salary are non-null fields */ IF DELETING OR (UPDATING AND :old.department_id != :new.department_id) THEN UPDATE departments SET total_salary = total_salary - :old.salary WHERE department_id = :old.department_id; END IF; IF INSERTING OR (UPDATING AND :old.department_id != :new.department_id) THEN UPDATE departments SET total_salary = total_salary + :new.salary WHERE department_id = :new.department_id; END IF; IF (UPDATING AND :old.department_id = :new.department_id AND :old.salary != :new.salary ) THEN UPDATE departments SET total_salary = total_salary - :old.salary + :new.salary WHERE department_id = :new.department_id; END IF; END;
For this example, suppose that one user's uncommitted transaction includes an update to the
total_salary column of a row in the
departments table. At this point, the
total_salary trigger is fired by a second user's SQL statement. Because the uncommitted transaction of the first user contains an update to a pertinent value in the
total_salary column (that is, a row lock is being held), the updates performed by the
total_salary trigger are not run until the transaction holding the row lock is committed or rolled back. Therefore, the second user waits until the commit or rollback point of the first user's transaction.
Oracle stores PL/SQL triggers in compiled form, just like stored procedures. When a
TRIGGER statement commits, the compiled PL/SQL code, called P code (for pseudocode), is stored in the database and the source code of the trigger is flushed from the shared pool.
PL/SQL User's Guide and Reference for more information about compiling and storing PL/SQL code
Oracle runs a trigger internally using the same steps used for procedure execution. The only subtle difference is that a user has the right to fire a trigger if he or she has the privilege to run the triggering statement. Other than this, triggers are validated and run the same way as stored procedures.
PL/SQL User's Guide and Reference for more information about stored procedures
Like procedures, triggers depend on referenced objects. Oracle automatically manages the dependencies of a trigger on the schema objects referenced in its trigger action. The dependency issues for triggers are the same as those for stored procedures. Triggers are treated like stored procedures. They are inserted into the data dictionary.