You are on page 1of 56

PL/SQL Triggers

1
Triggers
• A trigger is a statement that is executed
automatically by the system as a side effect of a
modification to the database.
• To design a trigger mechanism, we must:
– Specify the conditions under which the trigger is to be
executed.
– Specify the actions to be taken when the trigger
executes.
• Triggers were introduced in SQL:1999, but
supported even earlier using non-standard syntax
by most databases.

2
Triggering events and actions
• Triggering event can be insert, delete or update
• Triggers on update can be restricted to specific
attributes
– For example, after update of takes on grade
• Values of attributes before and after an update
can be referenced
– referencing old row as : for deletes and updates
– referencing new row as : for inserts and updates
• Triggers can be activated before an event, which
can serve as extra constraints. For example,
convert blank grades to null
3
Example
create trigger setnull_trigger before update of
takes
referencing new row as nrow
for each row
when (nrow.grade = ‘ ‘)
begin atomic
set nrow.grade = null;
end

4
Example
create trigger credits_earned after update of takes on (grade)
referencing new row as nrow
referencing old row as orow
for each row
when nrow.grade <> ’F’ and nrow.grade is not null
and (orow.grade = ’F’ or orow.grade is null)
begin atomic
update student
set tot_cred= tot_cred +
(select credits
from course
where course.course_id= nrow.course_id)
where student.id = nrow.id;
end;

5
Statement level triggers
• Instead of executing a separate action for each
affected row, a single action can be executed
for all rows affected by a transaction
– Use for each statement instead of for each
row
– Use referencing old table or referencing new
table to refer to temporary tables (called
transition tables) containing the affected rows
– Can be more efficient when dealing with SQL
statements that update a large number of rows

6
When Not To Use Triggers

• Triggers were used earlier for tasks such as


– Maintaining summary data (e.g., total salary of each
department)

– Replicating databases by recording changes to special


relations (called change or delta relations) and having
a separate process that applies the changes over to a
replica

7
When Not To Use Triggers contd.
• There are better ways of doing these now:
– Databases today provide built in materialized view
facilities to maintain summary data
– Databases provide built-in support for replication
• Encapsulation facilities can be used instead of
triggers in many cases
– Define methods to update fields
– Carry out actions as part of the update methods
instead of through a trigger

8
When Not To Use Triggers contd.
• Risk of unintended execution of triggers, for
example, when
– Loading data from a backup copy
– Replicating updates at a remote site
– Trigger execution can be disabled before such
actions.
• Other risks with triggers:
– Error leading to failure of critical transactions that
set off the trigger
– Cascading execution

9
About triggers
• Triggers are stored programs, which are
automatically executed or fired when some
events occur. Triggers are, in fact, written to be
executed in response to any of the following
events:
• A database manipulation (DML) statement
(DELETE, INSERT, or UPDATE).
• A database definition (DDL) statement (CREATE,
ALTER, or DROP).
• A database operation (SERVERERROR, LOGON,
LOGOFF, STARTUP, or SHUTDOWN).
10
• Triggers could be defined on the table, view,
schema, or database with which the event is
associated.

11
Benefits of Triggers
• Triggers can be written for the following purposes:
• Generating some derived column values automatically
• Enforcing referential integrity
• Event logging and storing information on table access
• Auditing
• Synchronous replication of tables
• Imposing security authorizations
• Preventing invalid transactions

12
Creating Triggers

The syntax for creating a trigger is:


CREATE [OR REPLACE ] TRIGGER trigger_name
{BEFORE | AFTER | INSTEAD OF } {INSERT [OR]
| UPDATE [OR] | DELETE} [OF col_name] ON
table_name [REFERENCING OLD AS o NEW AS
n] [FOR EACH ROW] WHEN (condition)
DECLARE Declaration-statements BEGIN
Executable-statements EXCEPTION Exception-
handling-statements END;

13
• Where,
• CREATE [OR REPLACE] TRIGGER trigger_name: Creates
or replaces an existing trigger with the trigger_name.
• {BEFORE | AFTER | INSTEAD OF} : This specifies when
the trigger would be executed. The INSTEAD OF clause
is used for creating trigger on a view.
• {INSERT [OR] | UPDATE [OR] | DELETE}: This specifies
the DML operation.
• [OF col_name]: This specifies the column name that
would be updated.

14
• [ON table_name]: This specifies the name of the table
associated with the trigger.
• [REFERENCING OLD AS o NEW AS n]: This allows you to
refer new and old values for various DML statements, like
INSERT, UPDATE, and DELETE.
• [FOR EACH ROW]: This specifies a row level trigger, i.e., the
trigger would be executed for each row being affected.
Otherwise the trigger will execute just once when the SQL
statement is executed, which is called a table level trigger.
• WHEN (condition): This provides a condition for rows for
which the trigger would fire. This clause is valid only for row
level triggers.

15
Example:

• To start with, we will be using the CUSTOMERS


table
• Consider a customer table having entries for
Id, Name, Age, Address, and Salary.

16
• SELECT * FROM CUSTOMERS;

Id Name Age Address Salary

1 Ramesh 32 Ahmedabad 2000.00


2 Khilan 25 Delhi 1500.00
3 Kaushik 23 Kota 2000.00
4 Chailtali 25 Mumbai 6500.00
5 Hardik 27 Bhopal 8500.00
6 Komal 22 MP 4500.00

17
Row level trigger
The following program creates a row
level trigger for the customers table that
would fire for INSERT or UPDATE or DELETE
operations performed on the CUSTOMERS
table. This trigger will display the salary
difference between the old values and new
values:

18
Example of row level trigger
CREATE OR REPLACE TRIGGER display_salary_changes
BEFORE DELETE OR INSERT OR UPDATE ON customers
FOR EACH ROW
WHEN (NEW.ID > 0)
DECLARE sal_diff number;
BEGIN sal_diff := :NEW.salary - :OLD.salary;
dbms_output.put_line('Old salary: ' || :OLD.salary);
dbms_output.put_line('New salary: ' || :NEW.salary);
dbms_output.put_line('Salary difference: ' || sal_diff);
END;
/

19
When the above code is executed at SQL
prompt, it produces the following result:
Trigger created.

20
Here following two points are important and should be noted
carefully:
• OLD and NEW references are not available for table level triggers,
rather you can use them for record level triggers.
• If you want to query the table in the same trigger, then you should
use the AFTER keyword, because triggers can query the table or
change it again only after the initial changes are applied and the
table is back in a consistent state.
• Above trigger has been written in such a way that it will fire before
any DELETE or INSERT or UPDATE operation on the table, but you
can write your trigger on a single or multiple operations, for
example BEFORE DELETE, which will fire whenever a record will be
deleted using DELETE operation on the table.

21
Triggering a Trigger
Let us perform some DML operations on the CUSTOMERS
table. Here is one INSERT statement, which will create
a new record in the table:
INSERT INTO CUSTOMERS
(ID,NAME,AGE,ADDRESS,SALARY) VALUES (7, 'Kriti', 22,
'HP', 7500.00 );
When a record is created in CUSTOMERS table, above
create trigger display_salary_changes will be fired and
it will display the following result:
Old salary:
New salary: 7500
Salary difference:
22
Because this is a new record so old salary is
not available and above result is coming as
null. Now, let us perform one more DML
operation on the CUSTOMERS table.
Here is one UPDATE statement, which will
update an existing record in the table:
UPDATE customers
SET salary = salary + 500 WHERE id = 2;

23
When a record is updated in CUSTOMERS
table, above create trigger
display_salary_changes will be fired and it will
display the following result:
Old salary: 1500
New salary: 2000
Salary difference: 500

24
An example
• The price of a product changes constantly. It is
important to maintain the history of the prices
of the products.
• We can create a trigger to update the
'product_price_history' table when the price
of the product is updated in the 'product'
table.

25
1) Create the 'product' table and
'product_price_history' table
CREATE TABLE product_price_history
(product_id number(5), product_name
varchar2(32), supplier_name varchar2(32),
unit_price number(7,2) );

26
CREATE TABLE product (product_id number(5),
product_name varchar2(32), supplier_name
varchar2(32), unit_price number(7,2) );
2) Create the price_history_trigger and execute
it.

27
CREATE or REPLACE TRIGGER
price_history_trigger BEFORE UPDATE OF
unit_price ON product FOR EACH ROW BEGIN
INSERT INTO product_price_history VALUES
(:old.product_id, :old.product_name,
:old.supplier_name, :old.unit_price); END; /

28
3) Let us update the price of a product.
UPDATE PRODUCT SET unit_price = 800
WHERE product_id = 100
Once the above update query is executed, the
trigger fires and updates the
'product_price_history' table.
4) If you ROLLBACK the transaction before
committing to the database, the data inserted
to the table is also rolled back.
29
Types of PL/SQL Triggers
There are two types of triggers based on the
which level it is triggered.

1) Row level trigger - An event is triggered for


each row upated, inserted or deleted.
2) Statement level trigger - An event is
triggered for each sql statement executed.

30
PL/SQL Trigger Execution Hierarchy
The following hierarchy is followed when a trigger is
fired.
1) BEFORE statement trigger fires first.
2) Next BEFORE row level trigger fires, once for
each row affected.
3) Then AFTER row level trigger fires once for
each affected row. This events will alternates
between BEFORE and AFTER row level triggers.
4) Finally the AFTER statement level trigger fires.

31
Example
• Let's create a table 'product_check' which we
can use to store messages when triggers are
fired.
CREATE TABLE product(Message varchar2(50),
Current_Date number(32));
• Let's create a BEFORE and AFTER statement
and row level triggers for the product table

32
1) BEFORE UPDATE, Statement Level: This
trigger will insert a record into the table
'product_check' before a sql update statement
is executed, at the statement level.
CREATE or REPLACE TRIGGER
Before_Update_Stat_product BEFORE UPDATE
ON product Begin INSERT INTO product_check
Values('Before update, statement
level',sysdate); END; /

33
2) BEFORE UPDATE, Row Level: This trigger will
insert a record into the table 'product_check'
before each row is updated.
CREATE or REPLACE TRIGGER
Before_Upddate_Row_product BEFORE
UPDATE ON product FOR EACH ROW BEGIN
INSERT INTO product_check Values('Before
update row level',sysdate); END; /

34
3) AFTER UPDATE, Statement Level: This
trigger will insert a record into the table
'product_check' after a sql update statement
is executed, at the statement level.
CREATE or REPLACE TRIGGER
After_Update_Stat_product AFTER UPDATE
ON product BEGIN INSERT INTO
product_check Values('After update,
statement level', sysdate); End; /

35
4) AFTER UPDATE, Row Level: This trigger will
insert a record into the table 'product_check'
after each row is updated.
CREATE or REPLACE TRIGGER
After_Update_Row_product AFTER insert On
product FOR EACH ROW BEGIN INSERT INTO
product_check Values('After update, Row
level',sysdate); END; /

36
Now lets execute a update statement on table
product.
UPDATE PRODUCT SET unit_price = 800 WHERE
product_id in (100,101); Lets check the data in
'product_check' table to see the order in
which the trigger is fired.
SELECT * FROM product_check;

37
Output:
Mesage Current_Date
------------------------------------------------------------
Before update, statement level 26-Nov-2008
Before update, row level 26-Nov-2008
After update, Row level 26-Nov-2008
Before update, row level 26-Nov-2008
After update, Row level 26-Nov-2008
After update, statement level 26-Nov-2008
38
• The above result shows 'before update' and
'after update' row level events have occured
twice, since two records were updated. But
'before update' and 'after update' statement
level events are fired only once per sql
statement.
• The above rules apply similarly for INSERT and
DELETE statements.

39
How To know Information about Triggers

• We can use the data dictionary view


'USER_TRIGGERS' to obtain information about
any trigger.
• The below statement shows the structure of
the view 'USER_TRIGGERS'
• DESC USER_TRIGGERS;

40
NAME Type
--------------------------------------------------------
TRIGGER_NAME VARCHAR2(30)
TRIGGER_TYPE VARCHAR2(16)
TRIGGER_EVENT VARCHAR2(75)
TABLE_OWNER VARCHAR2(30)
BASE_OBJECT_TYPE VARCHAR2(16)
TABLE_NAME VARCHAR2(30)
COLUMN_NAME VARCHAR2(4000)
REFERENCING_NAMES VARCHAR2(128)
WHEN_CLAUSE VARCHAR2(4000)
STATUS VARCHAR2(8)
DESCRIPTION VARCHAR2(4000)
ACTION_TYPE VARCHAR2(11)
TRIGGER_BODY LONG

41
• This view stores information about header and
body of the trigger.
SELECT * FROM user_triggers WHERE trigger_name
= 'Before_Update_Stat_product';
The above sql query provides the header and body
of the trigger 'Before_Update_Stat_product'.
• You can drop a trigger using the following
command.
DROP TRIGGER trigger_name;

42
CYCLIC CASCADING in a TRIGGER
• This is an undesirable situation where more than one trigger enters
into an infinite loop.
• While creating a trigger we should ensure the such a situation does
not exist.
• The below example shows how Trigger's can enter into cyclic
cascading.

Let's consider we have two tables 'abc' and 'xyz'. Two triggers are
created.
1) The INSERT Trigger, triggerA on table 'abc' issues an UPDATE on
table 'xyz'.
2) The UPDATE Trigger, triggerB on table 'xyz' issues an INSERT on
table 'abc'.

43
CYCLIC CASCADING in a TRIGGER contd.

• In such a situation, when there is a row


inserted in table 'abc', triggerA fires and will
update table 'xyz'.
When the table 'xyz' is updated, triggerB fires
and will insert a row in table 'abc'.
This cyclic situation continues and will enter
into a infinite loop, which will crash the
database.

44
DROP TRIGGER Statement
• Description
• Once you have created a trigger in Oracle, you might
find that you need to remove it from the database. You
can do this with the DROP TRIGGER statement.
• Syntax
• The syntax to a drop a trigger in Oracle in
Oracle/PLSQL is:
DROP TRIGGER trigger_name;Parameters or Arguments
trigger_name
• The name of the trigger that you wish to drop

45
• Example
• Let's look at an example of how to drop a
trigger in Oracle.
• For example:
• DROP TRIGGER orders_before_insert;This
example uses the ALTER TRIGGER statement
to drop the trigger
called orders_before_insert.

46
Disable a Trigger
• Description
• Once you have created a Trigger in Oracle, you
might find that you are required to disable the
trigger. You can do this with the ALTER
TRIGGER statement.
• Syntax
• The syntax for a disabling a Trigger in
Oracle/PLSQL is:
ALTER TRIGGER trigger_name DISABLE;
47
Parameters or Arguments
trigger_name
• The name of the trigger that you wish to
disable.

48
• Example
• Let's look at an example that shows how to
disable a trigger in Oracle.
• For example:
ALTER TRIGGER orders_before_insert DISABLE;
• This example uses the ALTER TRIGGER
statement to disable the trigger
called orders_before_insert.
49
Disable all Triggers on a table
• Description
• Once you have created Triggers in Oracle, you might find
that you are required to disable all of the triggers on a
table.. You can do this with the ALTER TRIGGER statement.
• Syntax
• The syntax for a disabling all Triggers on a table in
Oracle/PLSQL is:
ALTER TABLE table_name DISABLE ALL TRIGGERS;
Parameters or Arguments
table_name
• The name of the table that all triggers should be disabled
on.

50
• Example
• Let's look at an example that shows how to
disable all triggers on a table in Oracle.
• For example:
ALTER TABLE orders DISABLE ALL TRIGGERS;
• This example uses the ALTER TRIGGER
statement to disable all triggers on the table
called orders.
51
Enable a Trigger
• Description
• You may have found that you have disabled a trigger on
a table and you wish to enable the trigger again. You
can do this with the ALTER TRIGGER statement.
• Syntax
• The syntax for a enabling a Trigger in Oracle/PLSQL is:
ALTER TRIGGER trigger_name ENABLE;
Parameters or Arguments
trigger_name
• The name of the trigger that you wish to enable.

52
• Example
• Let's look at an example that shows how to
enable a trigger in Oracle.
• For example:
ALTER TRIGGER orders_before_insert ENABLE;
• This example uses the ALTER TRIGGER
statement to enable the trigger
called orders_before_insert.
53
Enable all Triggers on a table
• Description
• You may have found that you have disabled all triggers on a
table and you wish to enable the triggers again. You can do
this with the ALTER TRIGGER statement.
• Syntax
• The syntax to enable all triggers on a table in Oracle/PLSQL
is:
ALTER TABLE table_name ENABLE ALL TRIGGERS;
Parameters or Arguments
table_name
• The name of the table that all triggers should be enabled
on.

54
• Example
• Let's look at an example that shows how to
enable all triggers on a table in Oracle.
• For example:
ALTER TABLE orders ENABLE ALL TRIGGERS;
• This example uses the ALTER TRIGGER
statement to enable all triggers on the table
called orders.
55
References
• Database System Concepts, Sixth Edition, A.
Silberschatz, Henry F. Korth, and S.Sudarshan,
Mcgraw Hill Education, ISBN 0-07-352332-1,
Jan 2010
• http://www.tutorialspoint.com/plsql/plsql_tri
ggers.htm
• http://plsql-tutorial.com/plsql-triggers.htm
• https://www.techonthenet.com/oracle/trigger
s/drop.php
56

You might also like