Learn About Different Type Of Triggers In Oracle
SQL> select * from salary_bk;
Table created.
SQL>
SQL> create table student_details
Database
triggers are specialized stored programs. Oracle engine allow the
definition of procedure that are implicitly executed when an insert, update,
delete is issued again a table from sql or thought application the trigger
automatically associated DML statement is executed.They are not called directly
but are triggered by events in the database. They run between the time you
issue a commandand the time you perform the database management system action.
You can write triggers in PL/SQL.
PL/SQL
Type of Triggers based on how they triggered:-
Before
Triggers: These triggers are fired before the triggering SQL statement (INSERT,
UPDATE, DELETE) is executed. The execution of triggering SQL statement is
stopped depending on the various conditions to be fulfilled in BEFORE trigger.
After
Triggers: These triggers are fired after the triggering SQL statement (INSERT, UPDATE, DELETE) is executed. The
triggering SQL statement is executed first followed by the code of trigger.
ROW
Trigger: The triggers are fired for each and every record which is inserted or
updated or deleted from a table.
Statement
Trigger: The Trigger are fired for each row of DML operation being performed on
a table. we can not access the column values for records being inserted,
updated, deleted on the table and not individual records.
PL/SQL
Triggers Syntax Description:-
CREATE
or REPLACE TRIGGER trigger_name: Creates a trigger with the given name
otherwise overwrites an existing trigger with the same name.
{BEFORE
, AFTER }: Indicates the where should trigger get fired. BEFORE trigger execute
before when statement execute before time or AFTER trigger execute after when
statement execute after time.
{INSERT
, UPDATE , DELETE}: Determines the performing trigger event. More than one
triggering events allow can be used together separated by OR keyword.
ON Table
Name: Determine the perform trigger event in selected Table.
[Referencing
{old AS old, new AS new}]: Reference the old and new values of the data being
changed. :old use to existing row perform and :new use to execute new row to
perform. The reference names can also be changed from old (or new) to any other
user-defined name. You cannot reference old values when inserting a record, or
new values when deleting a record, because they do not exist.
Note:-
Insert
have no :OLD value ( before execution) and have :NEW value (After execution)
Delete
have no :OLD value but it have :NEW value.
Update
have both :OLD and :NEW value.
for each
row: Trigger must fire when each row gets Affected (Row Level Trigger) or just
once when the entire sql statement is executed(statement level Trigger).
WHEN
(condition): Valid only for row level triggers. The trigger is fired only for
rows that satisfy the condition specified.
There
are various events on which a trigger can be written, such as:
1.System
events
.....a.
Database startup and shutdown
.....b.
Server error message events
2.User
events
.....a.
User logon and logoff
.....b.
DDL statements (CREATE, ALTER, and DROP)
.....c.
DML statements (INSERT, DELETE, and UPDATE)
Based on
the above condition we can classify the trigger into 5 catogory dml trigger ,
ddl trigger ,Compound triggers, Instead-of triggers and
System or database event triggers. Out of which here i am discussing mainly ddl
and dml trigger.
1.DDL Trigger
DDL
triggers fire when you create, change or remove objects in a database, they
support both before and after event triggers and work at the database or schema
level.
DDL
event supported :-
alter,
analyze, associate statistics, audit, comment, create, ddl, disassociate
statistics, drop, grant, noaudit, rename, revoke, truncate .
There
are a number of event attribute functions that can be used to get user, client
or system information , commonly used are given below.
ORA_CLIENT_IP_ADDRESS
|
returns the client IP address as varchar2
|
ORA_DATABASE_NAME
|
returns database name as varchar2
|
ORA_DES_ENCRYPTED_PASSWORD
|
returns DES-encrypted password as varchar2
|
ORA_DICT_OBJ_NAME
|
returns object name as varchar2
|
ORA_DICT_OBJ_NAME_LIST
|
returns the number of elements in the list as a pls_integer
|
ORA_DICT_OBJ_OWNER
|
returns the owner of the object acted upon by the event as a
varchar2
|
ORA_DICT_OBJ_OWNER_LIST
|
returns the number of elements in the list as a pls_integer
|
ORA_DICT_OBJ_TYPE
|
returns the datatype of the dictionary object changed by the
event as a varchar2
|
ORA_GRANTEE
|
returns the number of elements in the list as a pls_integer
|
ORA_INSTANCE_NUM
|
returns the current database instance number as a number
|
ORA_IS_ALTER_COLUMN
|
returns true or false depending if the column has been altered
(true = altered)
|
ORA_IS_CREATING_NESTED_TABLE
|
returns a true or false value when you create a table with a
nested table
|
ORA_IS_DROP_COLUMN
|
returns true or false depending if the column has been dropped
(true = dropped)
|
ORA_IS_SERVERERROR
|
returns true or false when the error is on the error stack
|
ORA_LOGIN_USER
|
returns the current schema name as a varchar2
|
ORA_PARTITION_POS
|
returns the numeric position with the SQL text where you can
insert a partition clause
|
ORA_PRIVILEGE_LIST
|
returns the number of elements in the list as a pls_integer
|
ORA_REVOKEE
|
returns the number of elements in the list as a pls_integer
|
ORA_SERVER_ERROR
|
returns the error number as a number
|
ORA_SERVER_ERROR_DEPTH
|
returns the number of errors on the error stack as a
pls_interger
|
ORA_SERVER_ERROR_MSG
|
returns an error message text as a varchar2
|
ORA_SERVER_ERROR_NUM_PARAMS
|
returns the count of any substituted strings from error
messages as a pls_integer
|
ORA_SERVER_ERROR_PARAM
|
returns an error message text as a varchar2
|
ORA_SQL_TXT
|
returns the number of elements in the list as a pls_integer
|
ORA_SYSEVENT
|
returns the system event that was responible for firing the
trigger as a varchar2
|
ORA_WITH_GRANT_OPTION
|
returns true or false when privileges are granted with grant option (true = with grant
option)
|
SPACE_ERROR_INFO
|
returns true or false when the triggering event is related to
an out-of-space condition.Now for an example
|
Example.1
The below given ddl trigger prevent truncating table on schema level,
SQL> create or replace trigger prevent_truncates
2 before truncate on schema
3 begin
4 raise_application_error(-20001,'TRUNCATE not permitted');
5 end;
6 /
Trigger created.
SQL> create table salary_bk as select * from salary;
Table created.
SQL> select * from salary_bk;
ROLLNO EMPNAME DESIGN BPAY DA TA PF NETSAL
---------- --------------- --------------- ---------- ---------- ---------- ---------- ----------
10001 S.Krishnan HOD 25000 1500 1200 2250 27000
10002 K.K.Omana Asst.Manager 19500 1500 1200 1800 22000
10003 Anishkumar.K Asst.Manager 19500 1500 1200 1800 22000
10004 Girishkumar.K Asst.Manager 19500 1500 1200 1800 22000
SQL> truncate table salary_bk;
truncate table salary_bk
*
ERROR at line 1:
ORA-00604: error occurred at recursive SQL level 1
ORA-20001: TRUNCATE not permitted
ORA-06512: at line 2
SQL>
Example.2
Below given trigger update every create statement that happens in the schema level into
log_table,
SQL> CREATE TABLE log_table(
2 user_name VARCHAR2(100),
3 event_date DATE,
4 detail VARCHAR2(400));
Table created.
SQL>
CREATE OR REPLACE TRIGGER log_create_trigg
2 AFTER CREATE ON SCHEMA
3 BEGIN
4 INSERT INTO log_table
5 (user_name, event_date, detail)
6 VALUES
7 (USER, SYSDATE, 'created object is: ' || ora_dict_obj_name);
8 END;
9 /
Trigger created.
SQL> select * from log_table;
no rows selected
SQL> create table abc as select * from dba_users;
Table created.
SQL> col user_name for a12
SQL> col detail for a25
SQL> select * from log_table;
USER_NAME EVENT_DAT DETAIL
------------ --------- -------------------------
MAHI 19-OCT-12 created object is: ABC
2.Database event trigger
These triggers fire when a system activity occurs in the database, like the logon and logoff event triggers. They are useful for auditing information of system access. These triggers let you track system events and map them to users.
Example:-
Below given trigger logs the logging information into log_trigger_table table,
SQL> CREATE TABLE log_trigger_table (
2 user_name VARCHAR2(30),
3 event_date DATE,
4 action VARCHAR2(300));
Table created.
SQL> CREATE OR REPLACE TRIGGER logon_trigger
2 AFTER LOGON ON SCHEMA
3 BEGIN
4 INSERT INTO log_trigger_table
5 (user_name, event_date, action )
6 VALUES
7 (USER, SYSDATE, 'Logging On');
8 END;
9 /
Trigger created.
SQL> exit
Disconnected from Oracle Database 11g Enterprise Edition Release 11.2.0.1.0 - 64bit Production
With the Partitioning, OLAP, Data Mining and Real Application Testing options
C:\Users\DELL\node1>sqlplus
SQL*Plus: Release 11.2.0.1.0 Production on Fri Oct 19 17:39:19 2012
Copyright (c) 1982, 2010, Oracle. All rights reserved.
Enter user-name: mahi
Enter password:
Connected to:
Oracle Database 11g Enterprise Edition Release 11.2.0.1.0 - 64bit Production
With the Partitioning, OLAP, Data Mining and Real Application Testing options
SQL> select * from log_trigger_table;
USER_NAME EVENT_DAT ACTION
------------ --------- -----------------------------------
MAHI 19-OCT-12 Logging On
3.DML Trigger
These triggers fire when you insert, update, or delete data from a table. You can fire them once for all changes on a table, or for each row change, using statement- or row-level trigger types, respectively. DML triggers are useful to control DML statements. You can use these triggers to audit, check, save, and replace values before they are changed.
Example.1
Example.1
Below given example insert each record that will deleted from salary table into sal_deleted table,
SQL> select * from salary;
ROLLNO EMPNAME DESIGN BPAY DA TA PF NETSAL
---------- --------------- --------------- ---------- ---------- ---------- ---------- ----------
10001 S.Krishnan HOD 25000 1500 1200 2250 27000
10002 K.K.Omana Asst.Manager 20000 1500 1200 1800 22000
10003 Anishkumar.K Asst.Manager 20000 1500 1200 1800 22000
10004 Girishkumar.K Asst.Manager 20000 1500 1200 1800 22000
10005 Arunkumar.K Programmer 12000 1440 1320 1080 13800
SQL> create table sal_deleted(
rollno number(5), name varchar(15),
del_date date);
Table created.
SQL>
Now create the trigger,
SQL>ed sal_delete_trig
create or replace trigger sal_delete before delete
on salary for each row
begin
insert into sal_deleted values
(:old.rollno, :old.empname,sysdate);
end;
/
SQL> @sal_delete_trig
Trigger created.
SQL> delete from salary where rollno = 10005;
1 row deleted.
SQL> select * from salary;
ROLLNO EMPNAME DESIGN BPAY DA TA PF NETSAL
---------- --------------- --------------- ---------- ---------- ---------- ---------- ----------
10001 S.Krishnan HOD 25000 1500 1200 2250 27000
10002 K.K.Omana Asst.Manager 20000 1500 1200 1800 22000
10003 Anishkumar.K Asst.Manager 20000 1500 1200 1800 22000
10004 Girishkumar.K Asst.Manager 20000 1500 1200 1800 22000
SQL> select * from sal_deleted;
ROLLNO NAME DEL_DATE
---------- --------------- ---------
10005 Arunkumar.K 19-OCT-12
Example.2
Following trigger will insert the system time automatically into DOJ field while inserting records into student_details table,
SQL> create table student_details
2 (rollno number(5), name varchar(15),
3 dob date, doj date, dop date );
Table created.
SQL> ed student_details_trig;
create trigger student_details_trig before insert
on student_details for each row
begin
:new.doj := sysdate;
end;
/
SQL> @student_details_trig
Trigger created.
SQL> select * from student_details;
no rows selected
SQL> select sysdate from dual;
SYSDATE
---------
19-OCT-12
SQL> insert into student_details (rollno,name,dob) values (1001,'MAHESH','30-OCT-86');
1 row created.
SQL> select * from student_details;
ROLLNO NAME DOB DOJ DOP
---------- --------------- --------- --------- ---------
1001 MAHESH 30-OCT-86 19-OCT-12
SQL>
Here you can see DOJ is automatically inserted by the trigger..
Example.3
Following trigger will insert each records into salupdated table before update happens in salary table,
SQL> select * from salary;
ROLLNO EMPNAME DESIGN BPAY DA TA PF NETSAL
---------- --------------- --------------- ---------- ---------- ---------- ---------- ----------
10001 S.Krishnan HOD 25000 1500 1200 2250 27000
10002 K.K.Omana Asst.Manager 20000 1500 1200 1800 22000
10003 Anishkumar.K Asst.Manager 20000 1500 1200 1800 22000
10004 Girishkumar.K Asst.Manager 20000 1500 1200 1800 22000
SQL> create table salupdated(
2 rollno number(5),
3 empname varchar(15),
4 design varchar(15),
5 bpay number(8,2),
6 da number(6,2),
7 total number(8,2),
8 ta number(6,2));
Table created.
SQL> ed salupdate_trig
create or replace trigger salupdate_trig before update
on salary for each row
begin
insert into salupdated values
(:old.rollno, :old.empname, :old.design, :old.bpay, :old.da, :old.netsal, :old.ta);
end;
/
SQL> @salupdate_trig
Trigger created.
SQL> select * from salupdated;
no rows selected
SQL> update salary set BPAY=21000 where DESIGN='Asst.Manager';
3 rows updated.
SQL> select * from salary;
ROLLNO EMPNAME DESIGN BPAY DA TA PF NETSAL
---------- --------------- --------------- ---------- ---------- ---------- ---------- ----------
10001 S.Krishnan HOD 25000 1500 1200 2250 27000
10002 K.K.Omana Asst.Manager 21000 1500 1200 1800 22000
10003 Anishkumar.K Asst.Manager 21000 1500 1200 1800 22000
10004 Girishkumar.K Asst.Manager 21000 1500 1200 1800 22000
SQL> select * from salupdated;
ROLLNO EMPNAME DESIGN BPAY DA TOTAL TA
---------- --------------- --------------- ---------- ---------- ---------- ----------
10002 K.K.Omana Asst.Manager 20000 1500 22000 1200
10003 Anishkumar.K Asst.Manager 20000 1500 22000 1200
10004 Girishkumar.K Asst.Manager 20000 1500 22000 1200
SQL>
Example.4
Following dml trigger will raise an application error while trying to delete records belonging to Asst.Manager,
Following dml trigger will raise an application error while trying to delete records belonging to Asst.Manager,
SQL> select * from salary;
ROLLNO EMPNAME DESIGN BPAY DA TA PF NETSAL
---------- --------------- --------------- ---------- ---------- ---------- ---------- ----------
10001 S.Krishnan HOD 25000 1500 1200 2250 27000
10002 K.K.Omana Asst.Manager 19500 1500 1200 1800 22000
10003 Anishkumar.K Asst.Manager 19500 1500 1200 1800 22000
10004 Girishkumar.K Asst.Manager 19500 1500 1200 1800 22000
SQL> CREATE or REPLACE TRIGGER not_del
2 AFTER
3 DELETE ON salary
4 for each row
5
6 BEGIN
7 IF :old.DESIGN = 'Asst.Manager' THEN
8 raise_application_error(-20015, 'Not Delete this Row');
9 END IF;
10 END;
11 /
Trigger created.
SQL> delete from salary where rollno=10004;
delete from salary where rollno=10004
*
ERROR at line 1:
ORA-20015: Not Delete this Row
ORA-06512: at "MAHI.NOT_DEL", line 3
ORA-04088: error during execution of trigger 'MAHI.NOT_DEL
No comments:
Post a Comment