Download Triggers are procedures that are stored in the database and

Survey
yes no Was this document useful for you?
   Thank you for your participation!

* Your assessment is very important for improving the workof artificial intelligence, which forms the content of this project

Document related concepts

Microsoft Access wikipedia , lookup

Oracle Database wikipedia , lookup

Entity–attribute–value model wikipedia , lookup

Extensible Storage Engine wikipedia , lookup

Concurrency control wikipedia , lookup

Database wikipedia , lookup

Open Database Connectivity wikipedia , lookup

Microsoft SQL Server wikipedia , lookup

Microsoft Jet Database Engine wikipedia , lookup

Ingres (database) wikipedia , lookup

SQL wikipedia , lookup

Clusterpoint wikipedia , lookup

Database model wikipedia , lookup

Relational model wikipedia , lookup

PL/SQL wikipedia , lookup

Transcript
Database Laboratory
Creating Database Triggers
(Implementation in DBMS Oracle)
Author:
Aleksandra Werner, PhD
Database Laboratory, ...Triggers
-1-
1. Introduction.
Triggers are procedures written in PL/SQL (or C and Java) that are stored in the
database and execute ("fire") implicitly whenever a particular event takes place. In Oracle,
triggers fire whenever one of the following operations occurs: DML statements (INSERT,
UPDATE, or DELETE) on a particular schema object (table or, in some cases, a view), DDL
statements issued within a schema or database, user logon or logoff events, server errors,
database startup, or instance shutdown.
Triggers are similar to stored procedures. However, procedures and triggers differ in
the way that they are invoked. A procedure is explicitly executed by a user, application, or
trigger. Triggers (one or more) are implicitly fired (executed) when a triggering event occurs,
no matter which user is connected or which application is being used. More differences are
shown in table 1.
A database application with some SQL statements that implicitly fire several triggers
is stored in the database and the database stores triggers separately from their associated
tables.
2. Triggers usability.
Triggers can 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. A trigger could also restrict
DML operations to occur only at certain times during weekdays. Other uses for triggers are 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 sophisticated auditing

maintain synchronous table replicates

gather statistics on table access

modify table data when DML statements are issued against views
Gliwice, 2002
-2-
Database Laboratory, ...Triggers

publish information about database events, user events, and SQL statements to
subscribing applications
Although triggers are useful for customizing a database, they should be used only
when necessary. Excessive use of triggers can result in complex interdependencies, which
may 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.
Triggers can be used 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
o
database startup and shutdown,
o
server error message events,
user events
o
user logon and logoff,
o
DDL statements (CREATE, ALTER, and DROP),
o
DML statements (INSERT, DELETE, and UPDATE).
2.1. System Events
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.
Triggers can be used to make subscribing applications shut down completely when the
database shuts down. (For abnormal instance shutdown these triggers may not 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.
Gliwice, 2002
Database Laboratory, ...Triggers
-3-
2.2. User Events
User events that can fire triggers are related to user logon and logoff, DDL statements
and DML statements.
2.2.1 Triggers on LOGON and LOGOFF Events
LOGON and 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 USERID and USERNAME.

LOGON triggers fire after a successful logon of a user.

LOGOFF triggers fire at the start of a user logoff.
2.2.2 Triggers on DDL Statements
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).

BEFORE CREATE and AFTER CREATE triggers fire when a schema object is
created in the database or schema.

BEFORE ALTER and AFTER ALTER triggers fire when a schema object is altered
in the database or schema.

BEFORE DROP and AFTER DROP triggers fire when a schema object is dropped
from the database or schema.
2.2.3 Triggers on DML Statements
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. INSTEAD OF triggers can’t be used on views to publish events related to DML
statements; instead, they 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.
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 UID, USER, USERENV,
and SYSDATE), pseudocolumns, and columns. The columns may be prefixed by :OLD and
:NEW for old and new values.
Gliwice, 2002
-4-
Database Laboratory, ...Triggers

BEFORE INSERT and AFTER INSERT triggers fire for each row inserted into the
table.

BEFORE UPDATE and AFTER UPDATE triggers fire for each row updated in the
table.

BEFORE DELETE and AFTER DELETE triggers fire for each row deleted from the
table.
3. Parts of a Trigger
A trigger has three basic parts:

a triggering event or statement

a trigger restriction

a trigger action
3.1. Triggering Event or Statement
A triggering event or statement is the SQL statement, database event or user event,
that causes a trigger to be fired. 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 CREATE, ALTER, or DROP statement on any schema object,

a database startup or instance shutdown,

a specific error message or any error message,

a user logon or logoff.
3.2. Trigger Restriction
A trigger restriction specifies a Boolean (logical) expression that must be TRUE for
the trigger to fire. The trigger action is not executed if the trigger restriction evaluates to
FALSE or UNKNOWN. For example, the trigger restriction might be:
new.extra_money < new.salary
3.2.1 WHEN Clause
Optionally, a trigger restriction can be included in the definition only of a row trigger,
by specifying a Boolean SQL expression in a WHEN clause. The WHEN clause can’t be
Gliwice, 2002
Database Laboratory, ...Triggers
-5-
specified for INSTEAD OF triggers. If included, then the expression in the WHEN clause is
evaluated for each row that the trigger affects.
If the expression evaluates to TRUE for a row, then the trigger body is fired on behalf
of that row. However, if the expression evaluates to FALSE or NOT TRUE for a row
(unknown, as with nulls), then the trigger body is not fired for that row. The evaluation of the
WHEN clause does not have an effect on the execution of the triggering SQL statement (in
other words, the triggering statement is not rolled back if the expression in a WHEN clause
evaluates to FALSE).
For example, the trigger body wouldn’t run if the new value of Empno were zero,
NULL, or negative.
WHEN (new.empno = 0)
In more realistic examples, you might test if one column value is less than another.
The expression in a WHEN clause of a row trigger can include correlation names. The
expression in a WHEN clause must be a SQL expression and it cannot include a subquery.
A PL/SQL expression (including user-defined functions) can’t be used in the WHEN clause.
3.3. Trigger Action
A trigger action is the procedure, that contains the SQL statements and code to be
executed when a triggering statement is issued and the trigger restriction evaluates to TRUE.
A trigger action can contain SQL and PL/SQL or Java statements, define PL/SQL
language constructs (variables, constants, cursors, exceptions, and so on) or Java language
constructs, and call stored procedures. Additionally, for row triggers, the statements in a
trigger action have access to column values (new and old) of the current row being processed
by the trigger. Correlation names provide access to the old and new values for each column.
For example, trigger action might be:
BEGIN
UPDATE audit_table SET upd = upd + 1
WHERE user_name = ‘laboratory’ AND column_name IS NULL;
END;
4. Types of Triggers
This section describes the different types of triggers:

Row Triggers and Statement Triggers

BEFORE and AFTER Triggers

INSTEAD-OF Triggers

Triggers on System Events Database Triggers and User Events Application Trigger
4.1. Row Triggers and Statement Triggers
Gliwice, 2002
Database Laboratory, ...Triggers
-6-
While defining a trigger, the number of times the trigger action is to be executed can
be specified:

once for every row affected by the triggering statement (such as might be fired by an
UPDATE statement that updates many rows), or:

once for the triggering statement, no matter how many rows it affects.
4.2. Row Triggers
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 executed at all.
Row triggers are useful if the code in the trigger action depends on data provided by
the triggering statement or rows that are affected.
4.3. Statement Triggers
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 statementlevel DELETE trigger is fired only once, regardless of how many rows are deleted from the
table.
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, if a trigger makes
a complex security check on the current time or user, or if a trigger generates a single audit
record based on the type of triggering statement, a statement trigger is used.
4.4. BEFORE and AFTER Triggers
When defining a trigger, the trigger timing can be specified (it means whether the
trigger action is to be executed 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 table(s) 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.
4.5. BEFORE Triggers
BEFORE triggers execute the trigger action before the triggering statement is
executed. This type of trigger is commonly used in the following situations:
Gliwice, 2002
Database Laboratory, ...Triggers
-7-

When the trigger action should determine 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.
4.6. AFTER Triggers
AFTER triggers execute the trigger action after the triggering statement is executed.
AFTER triggers are used when you want the triggering statement to complete before
executing the trigger action.
4.7. Trigger Type Combinations
Using the options listed above, four types of row and statement triggers can be
created:
 BEFORE statement trigger
Before executing the triggering statement, the trigger action is executed.
 BEFORE row trigger
Before modifying each row affected by the triggering statement and before checking
appropriate integrity constraints, the trigger action is executed provided that the trigger
restriction was not violated.
 AFTER row trigger
After modifying each row affected by the triggering statement and possibly applying
appropriate integrity constraints, the trigger action is executed for the current row.
Unlike BEFORE row triggers, AFTER row triggers lock rows.
 AFTER statement trigger
After executing the triggering statement and applying any deferred integrity
constraints, the trigger action is executed.
Multiple triggers of the same type for the same statement for any given table
can be defined. For example two BEFORE statement triggers for UPDATE statements
on the EMP table could be defined. Multiple triggers of the same type permit modular
installation of applications that have triggers on the same tables. Also, Oracle snapshot
logs use AFTER row triggers, so you can design your own AFTER row trigger in
addition to the Oracle-defined AFTER row trigger.

INSTEAD-OF Triggers
INSTEAD-OF triggers provide a transparent way of modifying views that
cannot be modified directly through SQL DML statements (INSERT, UPDATE, and
Gliwice, 2002
Database Laboratory, ...Triggers
-8-
DELETE). These triggers are called INSTEAD-OF triggers because, unlike other
types of triggers, Oracle fires the trigger instead of executing the triggering statement.
Normal INSERT, UPDATE, and DELETE statements against the view can be
written 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.
5. Creating Triggers
5.1. Syntax for creating Statement Triggers
CREATE [OR REPLACE] TRIGGER trigger_name
timing event1 [OR event2 OR event3]
ON table_name
BEGIN | DECLARE
PL/SQL block
END;
You can combine several triggering events into one by takinkg advantage of the
special conditional predicates INSERTING, UPDATING, DELETING within the trigger
body.
5.2. Syntax for creating Row Triggers
CREATE [OR REPLACE] TRIGGER trigger_name
timing event1 [OR event2 OR event3]
ON table_name
[REFERENCING OLD AS old | NEW AS new]
FOR EACH ROW
[WHEN condition]
BEGIN | DECLARE
PL/SQL block
END;
5.3. Removing Triggers
To remove a trigger from the database, use syntax:
DROP TRIGGER trigger_name;
Gliwice, 2002
Database Laboratory, ...Triggers
-9-
5.4. Managing Triggers
Syntax for disabling or re-enabling a database trigger:
ALTER TRIGGER trigger_name DISABLE | ENABLE;
Syntax for disabling or re-enabling all triggers for a table:
ALTER TABLE table_name DISABLE | ENABLE ALL TRIGGERS;
Syntax for recompiling a trigger for a table:
ALTER TRIGGER trigger_name COMPILE;
6. Listing Information About Triggers
The following data dictionary views reveal information about triggers:

USER_TRIGGERS

ALL_TRIGGERS

DBA_TRIGGERS
To list information from a view, use syntax:
SELECT * FROM data_dictionary_view;
The new column, BASE_OBJECT_TYPE, specifies whether the trigger is based on
DATABASE, SCHEMA, table, or view. The old column, TABLE_NAME, is null if the base
object is not table or view.
The column ACTION_TYPE specifies whether the trigger is a call type trigger or a
PL/SQL trigger.
The column TRIGGER_TYPE includes two additional values: BEFORE EVENT and
AFTER EVENT, applicable only to system events.
The column TRIGGERING_EVENT includes all system and DML events.
The following data dictionary views reveal information about triggers compilation
errors:

USER_ERRORS

ALL_ ERRORS

DBA_ ERRORS
Gliwice, 2002
Database Laboratory, ...Triggers
10 -
Table 1.
Different types of Triggers - summary
Types of Triggers
INSTEAD OF
BEFORE
AFTER
STATEMENT
ROW

The code in the trigger  The code in the trigger  The code in the trigger
 The code in the trigger
 The code in the trigger
body
will
execute
body
will
execute
body will execute after
body executes once for
body executes once for
instead of the triggering
before the triggering
the triggering DML
each row affected by
the triggering event.
statement.
DML event.
event.
triggering event.

Is used for views, that
are
not
otherwise
modifiable.


Gliwice, 2002
Is fired once, even if no
rows are affected at all.
If the triggering event
affects no row(-s),
a row trigger is not
executed at all.
Database Laboratory, ...Triggers
- 11 -
Table 2.
Differences between Triggers and Procedures
Triggers
Procedure

Triggers are procedures, that are stored in the database and  Procedures are blocks of PL/SQL, which are explicitly invoked
implicitly (automatically) run (fired), when sth happens.
by a user, application, or trigger.

It doesn’t matter which user is connected or which application is 
Can take parameters whose value is passed to, populated by the
being used.
calling environment.

Triggers might be database triggers or an application triggers.

Procedures might be client-side or server-side.

Can be defined on tables and on views.

Can be defined on tables and on views.

Can be written in PL/SQL or Java and stored in the database, or

Can be written is PL/SQL.
they can be written as C callouts.

COMMIT, SAVEPOINT, ROLLBACK not allowed within the  COMMIT, SAVEPOINT, ROLLBACK allowed within the
trigger body.
procedure body.

The source code is compiled into p-code.

The source code is compiled into p-code.
Gliwice, 2002
Database Laboratory, ...Triggers
12 -
Table 3.
Syntax for Creating a Row Trigger
Components of
CREATE TRIGGER
statement
Trigger_name
Meaning
The name of the trigger. Trigger names must be unique with respect to other triggers in the same schema.
Trigger names do not need to be unique with respect to other schema objects, such as tables, views, and
procedures. For example, a table and a trigger can have the same name.
Timing
Indicates the time when the trigger fires in relation to the triggering event:
BEFORE
AFTER
INSTEAD OF
Event
Identifies the DML operation, that causes the trigger to fire:
INSERT
UPDATE [OF column]
DELETE
Table_name
Indicates the table associated with trigger.
Referencing
Specifies correlation names for the old and new values of the current row (the default are: OLD and:
NEW).
FOR EACH ROW
Designates the trigger to be a row trigger.
WHEN
Specifies the trigger restriction. This conditional predicate is evaluated for each row to determine whether or
not the trigger body is executed.
PL/SQL block
Is the trigger body, that defines the action performed by trigger, beginning with either DECLARE or
BEGIN, ending with END.
Gliwice, 2002
Database Laboratory, ...Triggers
- 13 -
7. PL/SQL
7.1. Anonymous PL/SQL block
The trigger body is defined with an anonymous PL/SQL block:
[DECLARE]
BEGIN
[EXCEPTIONS]
END;
7.2. PL/SQL control structures
Any PL/SQL procedure can be written using the basic control structures shown in
fig. 1.
Iteration
Selection
T
Sequence
F
F
T
Fig. 1. Control structures
7.2.1 Conditional control
The selection structure tests a condition, then executes one sequence of statements
instead of another, depending on whether the condition is true or false. A condition is any
variable or expression that returns a Boolean value (TRUE, FALSE, NULL).
There are three forms of IF statements:

IF – THEN

IF – THEN – ELSE

IF – THEN – ELSIF
 IF condition THEN
sequence_of_statements;
END IF;
 IF condition THEN
sequence_of_statements1;
ELSE
sequence_of_statements2;
END IF;
 IF condition1 THEN
Gliwice, 2002
Database Laboratory, ...Triggers
14 sequence_of_statements1;
ELSIF condition2 THEN
sequence_of_statements2;
ELSE
sequence_of_statements3;
END IF;
7.2.2 Iterative control
There are three forms of LOOP statements:
 LOOP (The EXIT statement forces a loop to complete unconditionally; the
EXIT-WHEN statement allows a loop to complete conditionally),

WHILE-LOOP,

FOR-LOOP.
 WHILE condition LOOP
sequence_of_statements;
END LOOP;
 LOOP
sequence_of_statements;
END LOOP;
 FOR counter IN [REVERSE] lower_bound..higher_bound LOOP
sequence_of_statements;
END LOOP;
7.2.3 Sequential control: GOTO and NULL statements
The GOTO statement branches to a label unconditionally. The label must be unique
within its scope and must precede an executable statement or PL/SQL block. When executed,
the GOTO statement transfers control to the labeled statement or block.
The NULL statement can make the meaning and action of conditional statements clear
and so improve readability.
8. Examples

Create a trigger to restrict all data manipulation events on the EMP table to certain
business hours, Monday through Friday.
Solution: as many triggers of the preceding different types as are need, might be created for
each type of DML statement (INSERT, UPDATE, or DELETE).
Gliwice, 2002
Database Laboratory, ...Triggers
- 15 -
CREATE OR REPLACE TRIGGER secure_emp
BEFORE INSERT OR UPDATE OR DELETE ON emp
BEGIN
IF (TO_CHAR (sysdate, ‘DY’) IN (‘SAT’,’SUN’)) OR
(TO_CHAR (sysdate, ‘HH24’) NOT BETWEEN ‘08’ AND ‘18’)
THEN
IF DELETING
RAISE_APPLICATION_ERROR is a server-side built-in procedure
that prints a message to the user and causes the PL/SQL block to fail.
THEN RAISE_APPLICATION_ERROR
(-20502, ‘You may delete only during normal hours’);
ELSEIF INSERTING
THEN RAISE_APPLICATION_ERROR
(-20500, ‘You may insert only during normal hours’);
ELSE
THEN RAISE_APPLICATION_ERROR
(-20504, ‘You may update only during normal hours’);
END IF;
END IF;
END;
Attention: when a database fails, triggering statement is automatically rolled back by the
Oracle Server.

Enforce referential integrity with a trigger. When the value of deptno changes in the
DEPT parent table, cascade the update to the corresponding rows in the EMP child
table.
Let DEPT be a relational table containing a list of departments,
CREATE TABLE dept (
deptno NUMBER,
deptname VARCHAR2(20),
manager_num NUMBER
);
Let EMP be a relational table containing the list of employees and the departments in
which they work.
CREATE TABLE emp (
empno NUMBER PRIMARY KEY,
empname VARCHAR2(20),
deptno NUMBER,
startdate DATE
Gliwice, 2002
Database Laboratory, ...Triggers
16 );
Gliwice, 2002
Database Laboratory, ...Triggers
- 17 -
Solution:
CREATE OR REPLACE TRIGGER cascade_updates
AFTER UPDATE OF deptno ON emp
FOR EACH ROW
BEGIN
UPDATE emp
SET emp.deptno = :new.deptno
WHERE emp.deptno = :old.deptno;
END;

Create an INSTEAD OF trigger for inserting rows into the MANAGER_INFO view,
which was creating in such way:
CREATE VIEW manager_info AS
SELECT e.name, e.empname, d.dept_type, d.deptno
FROM emp e, dept d
WHERE e.empno = d.mgr_no;
Solution:
CREATE OR REPLACE TRIGGER manager_info_insert
INSTEAD OF INSERT ON manager_info
FOR EACH ROW
BEGIN
IF NOT EXISTS SELECT * FROM emp
WHERE emp.empno = :new.empno
THEN
INSERT INTO emp VALUES (:new.empno, :new.name);
ELSE
UPDATE emp SET emp.name = :new.name WHERE emp.empno = :new.empno;
END IF;
IF NOT EXISTS SELECT * FROM dept
WHERE dept.deptno = :new.deptno
THEN
INSERT INTO dept VALUES (:new. deptno, :new.dept_type);
ELSE
UPDATE dept SET dept.dept_type = :new.dept_type
WHERE emp. deptno = :new. deptno;
END IF;
END;
Gliwice, 2002