Oracle® Database Concepts 11g Release 1 (11.1) Part Number B28318-01 |
|
|
View PDF |
This chapter discusses triggers, which are procedures stored in PL/SQL or Java that run (fire) implicitly whenever a table or view is modified or when some user actions or database system actions occur.
This chapter contains the following topics:
You can write triggers that fire whenever one of the following operations occurs:
DML statements (INSERT
, UPDATE
, DELETE
) on a particular table or view, issued by any user
DDL statements (CREATE
or ALTER
primarily) issued either by a particular schema/user or by any schema/user in the database
Database events, such as logon/logoff, errors, or startup/shutdown, also issued either by a particular schema/user or by any schema/user in the database
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 Database when a triggering event occurs, no matter which user is connected or which application is being used.
Figure 22-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 invoke a C procedure, which is useful for computationally intensive operations.
See Also:
Chapter 24, "SQL" for information on the similarities of triggers to stored procedures
This section includes the following topics:
Triggers supplement the standard capabilities of Oracle Database 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:
Automatically generate derived column values
Prevent invalid transactions
Enforce complex security authorizations
Enforce referential integrity across nodes in a distributed database
Enforce complex business rules
Provide transparent event logging
Provide auditing
Maintain synchronous table replicates
Gather statistics on table access
Modify table data when DML statements are issued against views
Publish information about database events, user events, and SQL statements to subscribing applications
See Also:
Oracle Database PL/SQL Language Reference for more information about triggersThis section includes the following topics:
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.
You can use both triggers and integrity constraints to define and enforce any type of integrity rule. However, Oracle strongly recommends that you use triggers to constrain data input only in the following situations:
To enforce referential integrity when child and parent tables are on different nodes of a distributed database
To enforce complex business rules not definable using integrity constraints
When a required referential integrity rule cannot be enforced using the following integrity constraints:
NOT NULL
, UNIQUE
PRIMARY KEY
FOREIGN KEY
CHECK
DELETE CASCADE
DELETE SET NULL
See Also:
"How Oracle Database Enforces Data Integrity" for more information about integrity constraintsA trigger has three basic components, each explained in this section:
Figure 22-2 represents each of these trigger components and is not meant to show exact syntax. The sections that follow explain each trigger component 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:
An INSERT
, UPDATE
, or DELETE
statement on a specific table (or view, in some cases)
A database startup or instance shutdown
A specific error message or any error message
A user logon or logoff
For example, in Figure 22-2, the triggering statement is:
... UPDATE OF parts_on_hand ON inventory ...
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 INSERT
and DELETE
statements, because they affect entire rows of information.
A triggering event can specify multiple SQL statements:
... INSERT OR UPDATE OR DELETE OF inventory ...
This part means that when an INSERT
, UPDATE
, or 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 false
or unknown
. In the example, the trigger restriction is:
new.parts_on_hand < new.reorder_point
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:
A triggering statement is issued.
The trigger restriction evaluates to true.
Like stored procedures, a trigger action can:
Contain SQL, PL/SQL, or Java statements
Define PL/SQL language constructs such as variables, constants, cursors, exceptions
Define Java language constructs
Invoke stored procedures
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:
Once for every row affected by the triggering statement, such as a trigger fired by an UPDATE
statement that updates many rows
Once for the triggering statement, no matter how many rows it affects
This section includes the following topics:
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 22-2 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:
Make a complex security check on the current time or user
Generate a single audit record
When defining a trigger, you can specify the trigger timing—whether the trigger action is to be run before or after the triggering statement. BEFORE
and AFTER
apply to both statement and row triggers.
BEFORE
and 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 INSERT
, UPDATE
, or DELETE
statement is issued against the view. BEFORE
and AFTER
triggers fired by DDL statements can be defined only on the database or a schema, not on particular tables.
See Also:
"Triggers on System Events and User Events" for information about how BEFORE
and AFTER
triggers can be used to publish information about DML and DDL statements
This section includes the following topics:
BEFORE
triggers run the trigger action before the triggering statement is run. This type of trigger is commonly used in the following situations:
When the trigger action determines whether the triggering statement should be allowed to complete. Using a BEFORE
trigger 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.
To derive specific column values before completing a triggering INSERT
or UPDATE
statement.
Using the options listed previously, you can create four types of row and statement triggers:
BEFORE statement trigger
Before executing the triggering statement, the trigger action is run.
BEFORE row trigger
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 statement trigger
After executing the triggering statement and applying any deferred integrity constraints, the trigger action is run.
AFTER row trigger
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 BEFORE
row
triggers, AFTER
row
triggers lock rows.
You can have multiple triggers of the same type for the same statement for any given table. For example, you can have two BEFORE
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 Database materialized view logs use AFTER
row
triggers, so you can design your own AFTER
row
trigger in addition to the Oracle-defined AFTER
row
trigger.
You can create as many triggers of the preceding different types as you need for each type of DML statement, (INSERT
, UPDATE
, or DELETE
).
See Also:
Oracle Database PL/SQL Language Reference for more information about trigger typesA compound trigger is a single trigger on a table that allows you to specify actions for each of four timing points:
Before the firing statement
Before each row that the firing statement affects
After each row that the firing statement affects
After the firing statement
The compound trigger body supports a common PL/SQL state that the code for each timing point can access. The common state is automatically destroyed when the firing statement completes, even when the firing statement causes an error.
The effect of the compound trigger is similar to what you could achieve with a simple trigger for each of the timing points for which you needed to code action, with an ancillary package to hold the state that these simple triggers would share. The obvious advantage of the compound trigger is that the required code is managed in a single compilation unit, but the more important advantage is that the lifetime of the compound trigger's state is automatically limited to the duration of the firing statement.
The compound trigger is useful when you want to accumulate facts that characterize the "for each row" changes and then act on them as a body at "after statement" time. Sometimes you are forced to use this approach (to avoid the mutating table error). Sometimes this approach gives better performance; for example, when maintaining a denormalized aggregate value in a master table in response to changes in a detail table, or when maintaining an audit table.
INSTEAD
OF
triggers provide a transparent way of modifying views that cannot be modified directly through DML statements (INSERT
, UPDATE
, and DELETE
). These triggers are invoked INSTEAD
OF
triggers because, unlike other types of triggers, Oracle Database fires the trigger instead of executing the triggering statement.
You can write normal INSERT
, UPDATE
, and DELETE
statements against the view and the INSTEAD
OF
trigger is fired to update the underlying tables appropriately. INSTEAD
OF
triggers are activated for each row of the view that gets modified.
This section includes the following topics:
Modifying views can have ambiguous results:
Deleting a row in a view could either mean deleting it from the base table or updating some values so that it is no longer selected by the view.
Inserting a row in a view could either mean inserting a new row into the base table or updating an existing row so that it is projected by the view.
Updating a column in a view that involves joins might change the semantics of other columns that are not projected by the view.
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 INSTEAD
OF
trigger can be used on object views as well as relational views that are not otherwise modifiable.
A view is inherently modifiable if data can be inserted, updated, or deleted without using INSTEAD
OF
triggers and if it conforms to the restrictions listed as follows. Even if the view is inherently modifiable, you might want to perform validations on the values being inserted, updated or deleted. INSTEAD
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.
INSTEAD
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 INSTEAD
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.
See Also:
Oracle Database PL/SQL Language Reference for more information about INSTEAD
OF
triggers
If the view query contains any of the following constructs, the view is not inherently modifiable and therefore, you cannot perform inserts, updates, or deletes on the view:
Set operators
Aggregate functions
GROUP BY
, CONNECT BY
, or START WITH
clauses
The DISTINCT
operator
Joins (however, some join views are updatable)
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.
See Also:
"Updatable Join Views"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 INSTEAD
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.
See Also:
Oracle Database PL/SQL Language Reference for more information about triggers on nested tables
Oracle Database SQL Language Reference for information on the CREATE TRIGGER
statement
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:
System events
Database startup and shutdown
Data Guard role transitions
Server error message events
User events
User logon and logoff
DDL statements (CREATE
, ALTER
, and DROP
)
DML statements (INSERT
, DELETE
, and UPDATE
)
Triggers on system events can be defined at the database level or schema level. The DBMS_AQ
package is one example of using database triggers to perform certain actions. For example, a database shutdown trigger is defined at the database level:
CREATE TRIGGER register_shutdown ON DATABASE SHUTDOWN BEGIN ... DBMS_AQ.ENQUEUE(...); ... END;
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.
This section includes the following topics:
Event publication uses the publish-subscribe mechanism of Oracle Streams 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.
See Also:
Oracle Streams Advanced Queuing User's Guide for information about the Oracle Streams Advanced Queuing implementation of Publish/Subscribe
Oracle Database PL/SQL Packages and Types Reference for information about the DBMS_AQ
package
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 user name. 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.
STARTUP
triggers fire when the database is opened by an instance. Their attributes include the system event, instance number, and database name.
SHUTDOWN
triggers 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 SHUTDOWN
triggers include the system event, instance number, and database name.
SERVERERROR
triggers 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.
DB_ROLE_CHANGE
triggers fire when a role transition (failover or switchover) occurs in a Data Guard configuration. The trigger notifies users when a role transition occurs, so that client connections can be processed on the new primary database and applications can continue to run.
User events that can fire triggers are related to user logon and logoff, DDL statements, and DML statements.
LOGON
and LOGOFF
triggers can be associated with the database or with a schema. Their attributes include the system event and user name, and they can specify simple conditions on USERID
and USERNAME
.
LOGON
triggers fire after a successful logon of a user.
LOGOFF
triggers 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 USERID
and USERNAME
.
DML triggers for event publication are associated with a table. They can be either BEFORE
or AFTER
triggers that fire for each row on which the specified DML operation occurs. You cannot use INSTEAD
OF
triggers on views to publish events related to DML statements—instead, you can publish events using BEFORE
or AFTER
triggers for the DML operations on a view's underlying tables that are caused by INSTEAD
OF
triggers.
See Also:
Oracle Database PL/SQL Language Reference for more information about event publication using triggers on system events and user events
A trigger is either enabled or disabled.
Table 22-1 Trigger Modes
For enabled triggers, Oracle Database automatically performs the following actions:
Oracle Database runs triggers of each type in a planned firing sequence when more than one trigger is fired by a single SQL statement. First, statement level triggers are fired, and then row level triggers are fired.
Oracle Database performs integrity constraint checking at a set point in time with respect to the different types of triggers and guarantees that triggers cannot compromise integrity constraints.
Oracle Database provides read-consistent views for queries and constraints.
Oracle Database manages the dependencies among triggers and schema objects referenced in the code of the trigger action
Oracle Database uses two-phase commit if a trigger updates remote tables in a distributed database.
Oracle Database fires multiple triggers in an unspecified, random order, if more than one trigger of the same type exists for a given statement; that is, triggers of the same type for the same statement are not guaranteed to fire in any specific order.
This section includes the following topics:
When a statement in a trigger body causes another trigger to fire, the triggers are said to be cascading. Oracle Database allows up to 32 triggers to cascade at simultaneously.
A relational database does not guarantee the order of rows processed by a SQL statement. Therefore, do not create triggers that depend on the order in which rows are processed.
See Also:
Oracle Database PL/SQL Language Reference for more information about creating triggers and the order in which they fireWhen 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 running 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:
Queries see the current read-consistent materialized view of referenced tables and any data changed within the same transaction.
Updates wait for existing data locks to be released before proceeding.
Oracle Database stores PL/SQL triggers in compiled form, just like stored procedures. When a CREATE TRIGGER
statement commits, the compiled PL/SQL code is stored in the database and the source code of the trigger is flushed from the shared pool.
See Also:
Oracle Database PL/SQL Language Reference for more information about compiling and storing triggersOracle Database runs a trigger internally using the same steps used for subprogram 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 subprograms.
See Also:
Oracle Database PL/SQL Language Reference for more information about stored subprogramsLike procedures, triggers depend on referenced objects. Oracle Database 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.
See Also:
Chapter 6, "Schema Object Dependencies"