Trigger Laboratory Manual in Oracle
Trigger Laboratory Manual in Oracle
6. PL/SQL
6.1. Database Object Synonyms
Synonyms allows for an alias to avoid schema notation. Private synonym: owned by the user.
Public synonym: available to all. Too many synonyms may be confusing. Coding standards may
require schema notation. Suppose HR is the owner of staff table and HR grant to retrieve Staff
table to Abebe and Abel. However, user Abebe and Abel must include HR schema notation to
retrieve staff table. E.g. Select * from HR.Staff;
To solve this problem, you should create synonym for Staff table. First the user must have a create
synonym system privilege to create a synonym.
Syntax: CREATE SYNONYM synonym_Name FOR Schema.tablename;
Example: CREATE SYNONYM Staff FOR HR.Staff;
2
Prepared by: Worku M.
end;
let's Insert a row into Student table:
SQL>Insert into Student Values('Abebe');
1 rows inserted.
One Row Inserted By Mr. HR
let's Update a row from Student table:
SQL>update Student Set Fname='Dereje' where Fname='Abebe';
1 rows updated.
One Row Updated By Mr. HR
let's Delete a row from Student table:
SQL>Delete from Student Where Fname='Dereje';
1 rows deleted.
One Row Deleted By Mr. HR
6.2.2. How to Audit a Table?
To perfume Auditing Should create another table called Student_Audit;
SQL>Create table Student_Audit(
New_Name varchar2(30),
Old_Name varchar2(50),
User_Name varchar2(20),
Entry_Date varchar2(80),
Operation varchar2(30)
); -- table STUDENT_AUDIT created.
3
Prepared by: Worku M.
Values(:New.Fname, Null, V_user, V_date, 'Insert');
ElsIf Updating Then
Insert into Student_Audit(New_Name, Old_Name, User_Name, Entry_Date, Operation)
Values(:New.Fname, :Old.Fname, V_user, V_date, 'Update');
ElsIf Deleting Then
Insert into Student_Audit(New_Name, Old_Name, User_Name, Entry_Date, Operation)
Values(Null, :Old.Fname, V_user, V_date, 'Delete');
End If;
end;
When you are executing the above trigger code the following interface displayed the press apply.
4
Prepared by: Worku M.
One row Updated By Mr. HR
Let’s check Student_Audit table to understand the effect of Update trigger;
SQL>Select * from Student_audit;
5
Prepared by: Worku M.
Next compile Student_backup trigger;
SQL>Create or replace trigger Student_Backup --Student Backup Trigger
Before Insert or Update or Delete on Student
For each row
Enable
Begin
If Inserting Then
Insert into Student_Backup(Fname)Values(:New.Fname);
ElsIf Updating Then
Update Student_Backup Set Fname=:New.Fname where Fname= :Old.Fname;
ElsIf Deleting Then
Delete From Student_Backup WherE Fname=:Old.Fname;
End If;
end; -- Click on Apply
6
Prepared by: Worku M.
Let’s check the backup table:
SQL>Select * From Student_Backup;
7
Prepared by: Worku M.
Let’s check the backup table:
SQL>Select * From Student_Backup;
Now let’s create table Department and check the changes in Schema_Audit table;
8
Prepared by: Worku M.
SQL>Create Table Department (DepName Varchar2(30), DepLocation Varchar2(40));
--table DEPARTEMNT created.
Let’s check Schema_Audit table
SQL>Select * from Schema_Audit;
SQL>Show User;
USER is HR
Let’s insert a record into Department Table and Truncate it:
SQL> Insert into Department values('IS', 'CCI-145');
SQL>Insert into Department values('SE', 'CCI-145');
Truncate is a DDL Statement so the trigger check the situation after Truncate executed:
SQL> Truncate Table Department; -- table DEPARTEMNT truncated.
Then let’s check Schema_Audit table:
SQL>Select * from Schema_Audit;
Next, let’s drop Department Table and Check Schema Audit Table:
SQL>Drop Table Department; -- table DEPARTEMNT dropped.
Drop is a DDL statement. Finally, Let’s View Schema_Aduit Table:
SQL> Select * from Schema_Audit;
9
Prepared by: Worku M.
database event trigger in its own schema if it has CREATE TRIGGERS system privilege. To create
a trigger on the database you must need ‘Administrative Database Trigger’ system privilege.
Syntax:
SQL>Create or Replace Trigger Trigger_name
Before | After Database_event on Database /Schema
Begin
PL/SQL code
End;
Let’s create a trigger for LOGON database event. Logon is a system level trigger. Now let’s create
a table that can store or hold all logon and logoff entries. Create table HR_Event_Audit:
SQL>Create Table HR_Event_Audit (
Event_type Varchar2(40),
Logon_date date,
Logon_time Varchar2(50),
Logoff_date date,
Logoff_time Varchar2(50)
); -- table HR_EVENT_AUDIT created.
Next, lets create a trigger that will fire when the user login next time and every time.
SQL>Create or Replace Trigger Hr_Logon_Audit
After Logon On Schema
Begin
Insert into HR_Event_Audit values(
Ora_sysevent,
Sysdate,
To_Char(Sysdate, 'HH24:MI:SS'),
Null,
Null);
Commit;
End; --TRIGGER HR_LOGON_AUDIT compiled
Let’s check HR_EVENT_AUDIT table:
SQL>Select * from HR_EVENT_AUDIT;
As we see the table is empty then let’s logoff HR schema and logon HR schema see the effect of
Trigger_logon_Audit event.
SQL>Show user
USER is HR
To disconnect HR use Disc Keyword.
SQL>DISC;
Here HR user disconnect from Oracle Database.
Then reconnect HR user into a database.
SQL>Connect HR/hr;
10
Prepared by: Worku M.
Then let’s check HR_EVENT_AUDIT Table.
SQL>Select * from HR_EVENT_AUDIT;
Now, let’s create Logoff Trigger which is executed before the user is logoff. Let’s create
Hr_Logoff_Audit Trigger.
SQL>Create or Replace Trigger Hr_Logoff_Audit
Before Logoff On Schema
Begin
Insert into HR_Event_Audit values(
Ora_sysevent,
Null,
Null,
Sysdate,
11
Prepared by: Worku M.
To_Char(Sysdate, 'HH24:MI:SS')
);
Commit;
End; --- TRIGGER HR_LOGOFF_AUDIT compiled
Logoff trigger is similar with Logon except it is executed before the schema logoff.
Let’s check Hr_Event_Audit table.
SQL>Select * from Hr_Event_Audit;
In order to control all schemas Logon and Logoff activities use high privilege user which is SYS
and create administrative level trigger. So connect SYS user into Oracle database.
SQL>Show user;
Let’s create a table that can hold all users of a database logon and logoff events. \
SQL>Create Table DB_Event_Audit (
User_name Varchar2(40),
Event_type Varchar2(40),
Logon_date date,
Logon_time Varchar2(50),
Logoff_date date,
Logoff_time Varchar2(50)
); -- table DB_EVENT_AUDIT created.
Let’s create a database level trigger that can audit all users of the database. To create Database
level trigger, you must Login as SYSDBA. The code is similar with the previous logoff except it
is ON a DATABASE level.
Create or Replace Trigger DB_Logoff_Audit
Before Logoff On Database
Begin
Insert into DB_Event_Audit values(
User,
Ora_sysevent,
Null,
Null,
12
Prepared by: Worku M.
Sysdate,
To_Char(Sysdate, 'HH24:MI:SS')
);
Commit;
End; -- TRIGGER DB_LOGOFF_AUDIT compiled
This trigger has database wide scope and use user attribute to display the user name.
Let’s Check DB_Event_Audit Table.
SQL>Select * from DB_Event_Audit;
May be your output is not the same as this one and you might also find some extra entry. Do not
worry.
6.2.7. Create Startup Trigger
How to Create Startup Trigger in Oracle Database?
System event startup trigger. Startup trigger is executed during the startup process of the database.
May be logon to the database as sys DBA or as a user who has Administer database trigger system
privilege.
SQL>Show user
USER is SYS
First create a Startup_Audit table
SQL>Create Table Startup_Audit (
Event_Type Varchar(30),
Event_Date Date,
Event_Time Varchar(30)
)
SQL>select * from Startup_Audit
13
Prepared by: Worku M.
);
End; -- TRIGGER DB_STARTUP_AUDIT compiled
Activity: Create database shutdown event trigger?
6.2.8. Create Instead-Of Insert Trigger
How to Create Instead-Of Insert Trigger in Oracle Database?
Using Instead-Of trigger you can control the default behavior of insert, update, delete and merge
on a view tables but not on a base tables. Uses of Instead of trigger.
• You can use them to make a non-updatable view updatable.
• Override the default behavior of views that are updatable.
Syntax:
SQL>Create or Replace Trigger trigger_name
Instead of operation
On view_name
For Each Row
Begin
--Your SQL code
End;
Instead-of Insert example.
Let’s create two tables Trainer and Course. First connect HR schema.
SQL>Create Table Trainer ( Full_Name Varchar(100)); --Trainer Table
SQL>Create Table Course ( Course_title Varchar(100));
Insert values into course and trainer table.
SQL>Insert Into Trainer Values ('Abebe Dawit');
SQL>Insert Into Course Values ('Oracle');
Then Create a view table to get a combine result.
SQL>Create view VW_Trainer_course as select Full_name, Course_title From Trainer, Course;
Let’s modify VW_Trainer_course view table may be insert, update and delete. The following error
is displayed.
SQL>Insert into Vw_Trainer_Course values('Solomon Tomas', 'C#')
Error starting at line 70 in command:
Error at Command Line:70 Column:1
Error report:
SQL Error: ORA-01779: cannot modify a column which maps to a non key-preserved table
01779. 00000 - "cannot modify a column which maps to a non key-preserved table"
*Cause: An attempt was made to insert or update columns of a join view which
map to a non-key-preserved table.
*Action: Modify the underlying base tables directly.
14
Prepared by: Worku M.
To solve this problem, write Instead-Of trigger for Vw_Trainer_Course view table.
--Instead of trigger
SQL>Create Or Replace Trigger Tri_Instead_View
Instead Of Insert On Vw_Trainer_Course
For Each Row
Begin
Insert Into Trainer (Full_Name) Values (:New.Full_Name);
Insert Into Course (Course_Title) Values (:New.Course_Title);
End; -- TRIGGER TRI_INSTEAD_VIEW compiled
Let’s insert a new row Vw_Trainer_Course view table without any modification problem.
SQL>Insert Into Vw_Trainer_Course Values('Solomon Tomas', 'C#');
1 rows inserted.
SQL>Insert Into Vw_Trainer_Course Values('Meklite Pawlose', 'Cisco');
1 rows inserted.
We can check both of the values are inserted in their respected table such as Trainer and Course.
Note: we have insert the above two rows into Vw_Trainer_Course view table but due to instead
of trigger the value is inserted into trainer and course tables.
SQL>Select * From Trainer;
15
Prepared by: Worku M.
SQL>Select * From Vw_Trainer_Course
16
Prepared by: Worku M.
Instead Of Update On Vw_Trainer_Course
For Each Row
Begin
Update Trainer Set Full_Name=:New.Full_Name Where Full_Name=:Old.Full_Name;
Update Course Set Course_Title=:New.Course_Title Where Course_Title=:Old.Course_Title;
End;
17
Prepared by: Worku M.
Let’s try to delete record from Vw_Trainer_Course view table.
SQL>Delete From Vw_Trainer_Course Where Course_Title='Oracle';
Error starting at line 48 in command:
delete from Vw_Trainer_Course where course_title='Oracle'
Error at Command Line:48 Column:13
Error report:
SQL Error: ORA-01752: cannot delete from view without exactly one key-preserved table
01752. 00000 - "cannot delete from view without exactly one key-preserved table"
*Cause: The deleted table either had no key perserved tables,
had more than one key-preserved table, or the key-preserved
table was an unmerged view or a table from a read-only view.
*Action: Redefine the view or delete it from the underlying base tables.
To solve the above error, Create Instead-of Delete trigger.
SQL>Create Or Replace Trigger Trdelete_Instead_View
Instead Of Delete On Vw_Trainer_Course
For Each Row
Begin
Delete From Trainer Where Full_Name=:Old.Full_Name;
Delete from Course Where Course_Title=:Old.Course_Title;
End;
18
Prepared by: Worku M.