Using triggers we can
create [or replace] trigger trigger_name
{before | after | instead of} triggering_event
[referencing_clause]
[when trigger_condition]
[for each row]
trigger_body;
| Category | Values | Comments |
|---|---|---|
| Statement | Defines which kind of DML statement causes the trigger to fire. | |
| Timing | before or after | Defines whether the trigger fires before or after the statement is executed. |
| Level | row or statement | If the trigger is a row-level trigger, it fires once for each row affected by the triggering statement. If the trigger is a statement-level trigger, it fires once, either before or after the statement. A row-level triggers are identified by the for each row clause. |
| Statement | :old | :new |
|---|---|---|
| insert | undefined - all fields are NULL | Values that will be inserted when the statement is complete |
| update | Original values for the row before the update | New values that will be updated when the statement is complete |
| delete | Original values before the row is deleted | undefined - all fields are NULL |
If desired, we can use the referencing clause to specify a different name for :old and :new. This clause has the following syntax:
referencing [old as old_name] [new as new_name]For example,
create or replace trigger GenerateProfID
before insert on Professors
referencing new as new_prof
for each row
begin
if :new_prof.pid is null then
select profids.nextval into :new_prof.pid from dual;
end if;
end GenerateProfID;
when trigger_conditionwhere trigger_condition is a Boolean expression. The :new and :old records can be referenced inside the expression, but like referencing, the colon is not used there. In the following example the trigger will be executed only for 'DB' department:
create trigger InsertStudent after insert or update on Student for each row when (new.mid = 'DB') begin /* put code here */ end InsertStudent;
create [or replace] trigger [schema.]trigger_name
{ before | after }
{ DDL_event_list | DB_event_list}
on { database | [schema.]schema }
[when condition]
trigger_body
| Event | Timing allowed | Description |
|---|---|---|
| startup | after | Fired when an instance is started up. |
| shutdown | before | Fired when an instance is shut down. This trigger may not fire if the DB is shutdown abnormally. |
| servererror | after | Fired whenever an error occurs. |
| logon | after | Fired after a user has successfully connected to the database. |
| logoff | before | Fired at the start of the logoff. |
| create | before, after | Fired before or after a schema object is created. |
| drop | before, after | Fired before or after a schema object is dropped. |
| alter | before, after | Fired before or after a schema object is altered. |
A system trigger can be defined at the database level trigger or a schema level trigger (keywords database and schema). A database-level trigger will fire whenever the triggering event occurs, whereas a schema-level trigger will fire only when the triggering event occurs for the specified schema. If the schema name is not specified with the schema keyword, it defaults to the schema that owns the trigger. The following trigger monitors all logons to the current schema
create or replace trigger MonitorLogons after logon on schema begin insert into danil.logons values (user, sysdate); end MonitorLogons;This trigger will monitor only the connections to the schema that owns this trigger, but if we change the keyword schema to database we will monitor all connections to the database. Don't forget that all users have to have the insert privilege on the table used in the trigger and also the person who creates the trigger should have enough privileges to do so. Please see more detailed example here. Please also read this chapter from Oracle documentation to better understand the difference between schema and database.
| Privilege | Description |
|---|---|
| create trigger | Allows the grantee to create a trigger in his or her own schema. |
| create any trigger | Allows the grantee to create triggers in any schema except SYS. |
| alter any trigger | Allows the grantee to enable, disable, or compile database triggers in any schema except SYS. |
| drop any trigger | Allows the grantee to drop database triggers in any schema except SYS. |
| administer database trigger | Allows the grantee to create or alter a system trigger on the database. The grantee must also have either create trigger or create any trigger privilege. |
| Function | Datatype | Event applicable for | Description |
|---|---|---|---|
| sysevent | varchar2(20) | All events | Returns the system event that fired the trigger |
| instance_num | number | All events | Returns the current instance number. This will always be 1 unless you are running with Oracle Real Application Cluster |
| database_name | varchar2(50) | All events | Returns the current database name. |
| server_error | number | servererror | Takes a single number argument. Returns the error at the position on the error stack indicated by the argument. The position 1 is the top of the stack. |
| is_servererror | boolean | servererror | Takes an error number as an argument, and returns true if the Oracle indicated is on the error stack. |
| login_user | varchar2(30) | All events | Returns the user ID of the user that fired the trigger. |
| dictionary_obj_type | varchar2(20) | create, alter, drop | Returns the type of the dictionary object on which the DDL operation that fired the trigger occurred. |
| dictionary_obj_name | varchar2(30) | create, alter, drop | Returns the name of the dictionary object on which the DDL operation that fired the trigger occurred. |
| dictionary_obj_owner | varchar2(30) | create, alter, drop | Returns the owner of the dictionary object on which the DDL operation that fired the trigger occurred. |
| des_encrypted_password | create or alter user | Returns the DES encrypted password of the user being created or altered. |
create or replace trigger MonitorCreation
after create on database
declare
msg TestCreateTrig.event%type;
begin
if sys.dictionary_obj_type = 'USER' then
msg := 'User ' || sys.login_user;
msg := msg || ' created user ' || sys.dictionary_obj_name;
msg := msg || ' identified by ' || sys.des_encrypted_password;
insert into system.TestCreateTrig values (user, sysdate, msg);
end if;
end MonitorCreation;
To drop a trigger user needs to execute the following command:
drop trigger trigger_name;This command permanently removes the trigger from the data dictionary. Of course, the user has to have enough privileges to successfully execute this command. Unlike procedures and packages, a trigger may be disabled without removing it. If a trigger is disables it still is in the data dictionary, but it cannot be fired. To disable a trigger, a user should execute the comand
alter trigger trigger_name disable;To enable the trigger back use
alter trigger trigger_name enable;All triggers for a particular table can be enable or disable with one alter table command:
alter table table_name {disable | enable} all triggers;