You are on page 1of 107

Exceptions

In PL/SQL, errors are called EXCEPTIONS

Types of Exceptions and Exception Handlers


Predefined internal exceptions
User-defined exceptions
PL/SQL's Exception Handlers
Conventional Error Handling
Exceptions

• Quick Notes:
– When an exception is raised, processing jumps to the
exception handlers.
– An exception handlers is a sequence of statements to be
processed when a certain exception occurs.
– when an exception handler is complete, processing of
the block terminates.
– Any ORACLE error "raises" an exception
automatically; some of the more common ones have
names.

!
@
Exceptions: Predefined
Internal
• TOO_MANY_ROWS (ORA -01427)
A single row SELECT returned more than one row
• NO_DATA_FOUND (ORA -01403)
A single row SELECT returned no data
• INVALID CURSOR (ORA-01001)
Invalid cursor was specified
• VALUE_ERROR (ORA-06502)
Arithmetic, numeric, string, conversion, or constraint error
occurred
• ZERO_DIVIDE (ORA-01476)
Attempted to divide by zero
• DUP_ VAL_ON_INDEX (ORA-00001)
Attempted to insert a duplicate value into a column that has a
unique index

!
@
Exception Handlers
Syntax

WHEN <exception name> [OR <exception


name>...] THEN <sequence of statements>

OR

WHEN OTHERS THEN --if used, must be last


handier
<sequence of statements>

!
Exception Handlers
DECLARE
employee_num emp.empno%TYPE;
BEGIN
SELECT empno INTO employee_num
FROM emp
WHERE ename = 'BLAKE';

INSERT INTO temp


VALUES (NULL, employee_num, 'BLAKE's employee
number.');

DELETE FROM emp WHERE ename = 'BLAKE';

--(Continued on next page) !


Exception Handlers
EXCEPTION -- (Continued from previous page)
WHEN TOO_MANY_ROWS OR NO_DATA_FOUND THEN
ROLLBACK;
INSERT INTO temp VALUES
(NULL, NULL,
'BLAKE NOT FOUND Or More than one Blake
');
COMMIT;
WHEN OTHERS THEN
ROLLBACK;
END;

!
Exceptions: User
defined
User - defined Exceptions must be defined and explicitly
raised by the user.

– DECLARE your exception


x NUMBER;
my_exception EXCEPTION; --- a new
object type

RAISE my_exception;

!
Exceptions: User
defined
• Quick Notes:
– Once an exception is RAISED manually, it is treated
exactly the same as if it were a predefined internal
exception
– Declared exceptions are scoped just like variables.
– A user defined exception is checked for manually and then
RAISED if appropriate.

!
Exceptions: User
defined
DECLARE
my_ename emp.ename%TYPE := 'BLAKE';
assigned_projects NUMBER;
too_few_projects EXCEPTION;
BEGIN
-- get number of projects assigned to BLAKE
....
IF assigned_projects < 3 THEN
RAISE too_few_projects;
ENDIF;
EXCEPTION -- begin the exception handlers
WHEN too_few_projects THEN
INSERT INTO temp
VALUES (my_ename,assigned_projects,'LESS THAN 3
PROJECTS!');
COMMIT;
...
END;
!
Exception: Propagation
– Step #1: The current block Is searched for a handler.
If not found, go to step 2.
– Step #2: If an enclosing block is found, It Is searched
for a handler.
– Step #3: Step # 1and step #2 are repeated until
either there are no enclosing blocks, or a
handler Is found.
• If there are no more enclosing blocks, the exception is passed
back to the calling environment (SQL'PIus, precompiled
program, etc.).

• If a handler is found it is executed. When done, the block in


which the handler was found is terminated, and control is
passed to the enclosing block (fl one exists), or to the
environment (if there is no enclosing block).

!
@
Exception: Propagation
BEGIN
….
• Exception A:
BEGIN – Is handled locally in the inner block
IF X = 1 THEN and execution resumes in the outer
RAISE A; block.
ELSIF X=2 THEN
RAISE B; • Exception B:
ELSE – Propagates to the first outer block
RAISE C;
with an appropriate handler
EXCEPTION – Is handled in the outer block and
WHEN A THEN control is passed back to the calling
… environment
END;
• Exception C:
EXCEPTION
– Has no handler and will result in a
WHEN B THEN runtime unhanded exception

END;

Calling Environment

!
Exception: Propagation
• Quick Notes:
– Only one handler per block may be active at a time.

– If an exception is raised in a handler, the search for a


handler for the new exception begins in the enclosing
block of the current block.
– By itself, the RAISE statement simply re-raises the
current exception (as if it were being propagated).
– RAISE may only be used in an exception handler.

!
Exception: Propagation
DECLARE

out_of_balance EXCEPTION;

BEGIN

..

BEGIN -- sub block begins

..

if (some condition) then

RAISE out_of_balance; --raises the exception

end if;

EXCEPTION

when out_of_balance then !


Exception: Propagation
CONTD..

--handle the error

RAISE; -- re raise the EXCEPTION

..

END; ---sub block ends

EXCEPTION

WHEN out_of_balance then

-- handle the error differently

..

END; !
EXCEPTION_INIT
• Exceptions may only be handled by name (not ORACLE error
number)
• EXECEPTION_INIT allows naming of ORACLE error.
Syntax:
PRAGMA EXCEPTION_INIT (<user defined exception
name>,
<ORACLE_error_number>);

Example:
DECLARE
deadlock_detected exception;
PRAGMA EXCEPTION_INIT
(deadlock_detected,-60);

!
@
Error Reporting
Functions
• SQLCODE and SQLERRM
– Provides information on the exception currently being
handled.
– Especially useful in the OTHERS handler.
• SQLCODE
– Returns the ORACLE error number of the exception or I if
it was a user-defined exception.
• SQLERRM
– Returns the ORACLE error message currently associated
with the current value of SQLCODE.
– May also use any ORACLE error number as an argument

!
@
Error Reporting
Functions

• Quick Notes - Error Reporting


– if no exception is active...
SQLCODE = 0
SQLERRM = 'normal, successful completion'
– SQLCODE and SQLERRM cannot be used
within a SQL statement

!
Error Reporting
Functions
DECLARE
sqlcode_val NUMBER;
sqlerrm_val CHAR(70);
BEGIN
...…

EXCEPTION
WHEN OTHERS THEN
sqlcode_val := SQLCODE; -- can't insert directly
sqlerrm_val := SQLERRM; -- ditto
INSERT INTO temp
VALUES (sqlcode_val,NULL, sqlerrm_val);

END;

!
Procedures, Functions and
Packages
– Procedures, Functions and Usage
– Creating, Altering and Dropping
– Executing
– Arguments
– Debugging
– Dependency
– Benefits
– Packages and its Usage
– Creating, Accessing, Dropping
– Benefits
– DBMS Packages
!
Procedures, Functions and
Packages
• Collection of SQL and PL/SQL statements
• Stored in compiled form in the database
• Can call others and self
• Can be called from all client environments
• Procedures and functions (including remote)are
the same, except a function returns a value and a
procedure does not

!
Uses for procedures
• Define central well-known business functions
– Create an order
– Delete a customer
• Store batch job in the database
– Weekly account rollups
• Encapsulate a transaction
– Gather and process information from remote nodes
• Funnel activity on a table through a single path
– All changes to employee salaries should change
department budgets

!
Creating a Procedure

Syntax:
CREATE OR REPLACE
PROCEDURE [ schema.] procedure
( argument [ IN ] [OUT ] [ INOUT ]

datatype …) [ IS ] [ AS ]
pl/sql_subprogram_body

!
Creating a Procedure
Argument modes
• IN
– Data value comes in from the calling process
and is not changed (the default)
• OUT
– No data value comes in from the calling
process; on normal exit (no error), value of
argument is passed back to caller
• IN OUT
– Data value comes in from the calling process,
and another value is returned on normal exit
!
@
Creating a Procedure

Example
CREATE PROCEDURE
fire_employee (empid NUMBER) AS

BEGIN

....

DELETE FROM emp

WHERE empno =
fire_employee.empid;
END;

Tip: Write each procedure in a text file, and save


!
Creating and Changing a
Function
Syntax:
CREATE OR REPLACE
FUNCTION [ schema.] function
(argument datatype )
RETURN datatype
[ IS ] [ AS ] subprogram_body

Note: Every function must return a value of the specified


type using RETURN statement

!
Creating and Changing a
Function
Example:
CREATE FUNCTION
get_sal (emp_no NUMBER)
RETURN NUMBER
IS emp_sal NUMBER (11,2);

BEGIN
SELECT empno
INTO emp_sal
FROM emp
WHERE empno = emp_no;

RETURN (emp_sal);
END;

!
Changing a Procedure
• To modify a procedure, replace it:
– CREATE OR REPLACE PROCEDURE
– fire employee AS . . END;
• OR REPLACE option:
– Recreates the procedure even if it already exists
– Retains existing grants (need not reissue)
– Creates procedure even if there are syntax errors
– Marks dependent objects for recompilation
– Users executing old procedure finish that call: next
invocation gets new procedure
– Facilitates development (one step)
• CREATE without OR REPLACE on existing
procedure fails
!
Dropping a Procedure
Example:
DROP PROCEDURE fire_employee;

• Marks dependent objects for recompilation

!
Statements in
Procedure
• Valid statements in a procedure or function
– SQL DML or PL/SQL statements
– Calls to other procedures and functions stored in the
database
– Calls to other procedures and functions in a remote
database
• Restricted statements
– DDL
– Dynamic SQL
– In triggers, COMMIT, SAVEPOINT, and ROLLBACK

!
@
Executing a Stored
Procedure
• From within a PL/SQL.block
fire_employee (empno)
scott. fire_employee (empno)
• On a remote node
scott. fire_employee@ny (empno)
• From SQL*DBA and some ORACLE tools
EXECUTE fire employee (1043)
• Within an anonymous block (when EXECUTE not
available)
SQL> BEGIN fire_employee(1043); END;
• From a precompiler application
EXEC SQL
fire_employee (:empno);

!
@
Privileges for
Procedures
Example
GRANT EXECUTE
ON scott.hire_fire
TO mkennedy
WITH GRANT
• Procedure executes under the authority of owner,
not user executing procedure
• User of procedure need not have access to objects
inside procedure
• Can only GRANT privileges on an entire package,
not a procedure, function, or variable defined in
the package
!
Privileges for
Procedures
PROCEDURE system privileges apply to packages, procedures, functions.

To Do this Need Either And

CREATE Create procedure or Owner must have access


Create any procedure System to all objects referenced in
privilege the procedure
ALTER Own the procedure or ALTER ANY
PROCEDURE system privilege
DROP Own the procedure or DROP ANY
PROCEDURE system privilege
Execute a Own the procedure or be granted Procedure owner must be
procedure EXECUTE PRIVILEGE or explicitly granted access to
or access a EXECUTE ANY PROCEDURE all database objects in the
package system privilege procedure (not through
construct roles)

!
@
Procedures Storage in the
Database
PL/SQL engine compiles the source code
ORACLE stores a procedure in a database:
– Object name
– Source code
– Parse tree
– Pseudo code (P-code)
– Syntax errors in dictionary table
– Dependency information
SQL in procedure not stored in parsed form
– Uses shared and cached SQL
– Allows SQL to be 0ptimized dynamically (without
recompiling referencing procedures)
!
@
PL/SQL Compilation
Errors
• Compile done by PL/SQL engine in RDBMS
• Errors stored in the database
• To view errors:
– Use command SHOW ERRORS
– Select from errors views
• USER_ERRORS
• ALL_ERRORS
• DBA_ERRORS

!
@
PL/SQL Compilation Errors:
SHOW ERRORS
SVRMGR> create procedure test1 is begin test2 ;
end;
DBA-00072: Warning: PROCEDURE TEST1 created with
compilation errors.

SVRMGR> show errors

ERRORS FOR PROCEDURE TEST1:


LINE/COL ERROR
----------------------------------------------------
-----
1/0 PL/SQL: Compilation unit analysis
terminated
1/33 PL/SQL-00219: 'test2' is not defined'

2 rows selected.
!
PL/SQL Compilation Errors: SHOW ERRORS

• Fields in ERRORS views


– NAME: name of the object
– TYPE: one of the following:
• PROCEDURE
• FUNCTION
• PACKAGE
• PACKAGE BODY
– LINE: line number where error occurs
– POSITION:column in line where error occurs
– TEXT:text of error

!
User-defined System
Errors
• Any procedure can raise an error and return a
user-defined error message and error number
– Error number range is -20000 to -20999
– Range always reserved for user-defined errors
– Oracle does not check if user-defined error numbers are
used uniquely
• Raise error within PI/SQL block with procedure
– raise_application_error (error_number, 'Text of the
message')
– sys.standard_utilities.raise_application error

!
@
User-defined System Errors
Example:
CREATE PROCEDURE
fire_employee (empid NUMBER)
AS BEGIN
IF empid <= 0 THEN
raise_application_error(-20100,
'Employee number must be
> 0');
ELSE
DELETE FROM emp
WHERE empno=empid;
END IF;
END;

SVRMGR> EXECUTE fire_employee(-1);


ORA-20100: Employee number must be >0

!
Data Dictionary Views for Procedures

Source Code Information


– Views:
• USER_SOURCE
• ALL_SOURCE
• DBA_SOURCE

– Fields
• OWNER: Owner of object
• NAME: Name of the object
• TYPE: PROCEDURE, FUNCTION, PACKAGE, or
PACKAGE BODY
• LINE: Line number of this line of source
• TEXT: Source text

!
Data Dictionary Views for Procedures

Dependency information
– Views:
• USER_DEPENDENCIES
• ALL_DEPENDENCIES
• DBA_DEPENDENCIES
– Fields
• OWNER: Owner of object
• NAME: Name of the object
• TYPE: Type of object
• TIMESTAMP: When last compiled
• PARENT_NAME: Owner of parent object
• PARENT_TYPE: Type of parent object
• PARENT_LINK_OWNER: Owner of remote link (if used)
• PARENT_LINK_NAME: Name of remote link (if used)
• PARENT_TIMESTAMP: when parent was last compiled
• ORDER_NUMBER: Level of dependency

!
Dependencies and
Procedures
• A procedure is dependent on:
– every database object to which it refers (direct
dependency)
procedures, functions, packages,tables, views, synonyms,
sequences
– the database objects those objects depend on (indirect
dependency)
• Two types of dependencies:
– Local: objects are on the same node
– remote: objects are on separate nodes
• ORACLE automatically checks dependencies

!
Dependencies and
Procedures
Table T
Procedure P Indirect
dependency

View of T
Direct Direct
dependency dependency

!
Dependencies for Remote Procedure
Calls
• Remote procedure calls from one server to another
fire_empl@ny(a,b,c);
• Protected by two-phase commit
• Dependency checking
– Timestamp of remote procedure checked at runtime
– Local procedure Is automatically recompiled if timestamp
of remote procedure differs from its value at last
execution
– Note: Current execution fails - procedure is recompiled
and executed on next execution

!
Dependencies for Remote Procedure
Calls

• Client-side calls to stored procedure (E.g:


Forms to database)
• No auto recompile on client-side
• Runtime error issued if timestamps for
remote procedure don't match

!
Recompilation of Dependent
Procedures

• When an object changes, its dependent


objects are marked for recompilation
• Any change to definition of referenced object
implies new version of referenced object
• Dependent objects must be recompiled if
referenced object changes
• Recompilation of dependent objects takes
place automatically at runtime

!
Recompilation
• Reasons recompilation could fail
– Changing parameter list in called procedure
– Changing definition of or removing referenced column
from referenced table
– Dropping referenced table
• If recompilation fails, error information is put to
error table
• Procedure/function can be recompiled by either:
– RDBMS automatically, when next accessed (Only if
marked for recompilation)
– Manually by the user, using ALTER PROCEDURE
command “ALTER PROCEDURE add_department COMPILE;”

!
Benefits of Procedures
• Security
– Executes under security domain of procedure's owner
– Provides controlled indirect access to database
objects to non-privileged users

• Integrity
– Defines allowed operations on data
– Ensures related actions are performed together

!
Benefits of Procedures

• Performance
– Reduces number of calls to the database
– Decreases network traffic
– Pre-parses PL/SQL statements

• Memory savings
– Takes advantage of shared SQL
– Requires only one copy of the code for multiple
users

!
Benefits of Procedures
• Productivity
– Avoids redundant code for common procedures in
multiple applications
– Reduces coding errors: no redundant code written

• Maintainability
– Enables system-wide changes with one update
– Makes testing easier: duplicate testing not needed
– Dependency tracked by ORACLE

• High availability
– Allows changing procedures on-line while users
execute previous version
!
Package
• A database object that groups related package
constructs
• procedures
• functions
• cursor definitions
• variables and constants
• exception definitions

– Package variables and cursors have persistent state


– Variables retain values and cursors retain contexts and
positions for the duration of a user session
– State persists across a user's calls in one session (not
multiple sessions or users)

!
Parts of a Package
• Package specification
– Declares (specifics) package constructs, including
names and parameters of publicly available procedures
and functions
• Package body
– May declare additional, private package constructs that
are not publicly available
– Defines all package constructs(public and private)
– May be replaced without affecting package
specification
(Breaks dependency chain)
– Each session has own version of state
!
Public and Private Package
Constructs

• Public package constructs


– Declared in the package specification
– Available to anyone who can run the package
• Private package constructs
– Only declared in the package body
– Available only to other package constructs
within the package body
– Allows hiding procedures from programmers
referencing the public constructs

!
Public and Private Package
Constructs
PACKAGE hire_fire IS
PROCEDURE hire_employee (..);
Public PROCEDURE fire_employee(..);
declarations valid CHAR(1);
END;
PACKAGE BODY hire_fire IS
PROCEDURE hire_employee(..)
Definition of IS
public BEGIN.. END;
constructs
PROCEDURE hire_employee(..)
IS
BEGIN.. END;
Definition of FUNCTION check_num(..)
private RETURN.. IS
function BEGIN.. END;
END;

!
@
Uses of Packages
• Group related constructs
• Declare globally accessible variables
• Declare variables with persistent state
• Organise development activity
Define modules, collections of procedures
known to one team
• Minimise name conflicts within a schema
personnel.audit is not equal to inventory.audit

!
Uses of Packages
• Simplify security
GRANT EXECUTE on entire package (not
individual constructs)
• Limit recompilation
Change body of procedure or function without
changing specification
• Limit indirect dependencies

!
Creating a Package Specification
Syntax:
Create [or replace] package [schema.] package
is/ as <PL/SQL Package specification>
Example:

CREATE PACKAGE journal_entries AS


PROCEDURE journalize (amount NUMBER,
trans_date VARCHAR2);
PROCEDURE journalize (amount NUMBER,
trans_date NUMBER );
END journal_entries;

!
@
Creating a Package Specification

Example:
CREATE PACKAGE BODY journal_entries AS
PROCEDURE journalize (amount NUMBER, trans_date
VARCHAR2) IS
BEGIN
INSERT INTO TEMP(num,diary)
VALUES (amount, TO_DATE(trans_date, 'DD-MON-
YYYY'));
END journalize;
PROCEDURE journalize (amount NUMBER, trans_date NUMBER)
IS
BEGIN
INSERT INTO journal
VALUES (num, TO_DATE(trans_date, 'J'));
END journalize;
END journal_entries;

!
@
Dropping Packages
Syntax:
DROP PACKAGE [schema.] package

Example:
DROP PACKAGE hire_fire;

– Drops both package specification and body Marks for

recompilation any dependent objects

!
DBMS Packages
• DBMS_OUTPUT :
display output from from PL/SQL blocks. The put_line procedure
outputs information to a buffer in SGA.

CREATE PROCEDURE calc_payroll


(Payroll IN OUT REAL )
BEGIN
payroll:=0;
select sal into payroll from emp;
dbms_output.put_line('payroll', ||
'payroll');
END calc_payoll;
SQL> SET SERVEROUTPUT ON;
SQL> EXECUTE calc_payroll;

!
@
DBMS Packages
• DBMS_SQL : allows PL/SQL to execute SQL data definition and data
manipulation statements dynamically at run time.

• DBMS_STANDARD: provides language facilities, that help your application


interact with ORACLE
raise_application_error(error_message,
message[, TRUE|FALSE]);
•DBMS_PIPE : allows different sessions to communicate over named pipes.( A
pipe is an area of memory used by one process to pass information to another.

•DBMS_ALERT : lets you use database triggers to alert an application when


specific database values change. E. g. A company might use this package to update
the value of it's investment portfolio as new stock and bond quotes arrive.

• UTL_FILE : allows your PL/SQL programs to read and write operating


system(OS ) text files.

!
@
Benefits of Packages
• Performance
– Reduces disk I/O for subsequent calls
(First call to package loads whole package into memory)
• Persistent state
– Retains values of package constructs for an entire
session
• Security
– Access to the package allows access to public
constructs in the package only
– No need to issue GRANT for every procedure in
package

!
Benefits of Packages
• Productivity
– Stores related procedures and functions together
– Easier to manage changing the specification or
definition of a construct
– Reduces cascading dependencies
– Dependencies are at package, not procedure level
– Can change package body without changing or
affecting package specification

!
Triggers
• What is a trigger
• Stored procedures v/s Triggers
• Database v/s Forms triggers
• Creating triggers
• Types of Triggers
• Restrictions on triggers
• Enabling and disabling
• Dropping and recompiling
• Privileges required
• Applications
• Benefits
!
What is a Trigger ?

A trigger defines an action the database should take


when some database related event occurs. Trigger
may be used to supplement declarative referential
integrity, to enforce complex business rules or to
audit changes of data. The code within the trigger is
called Trigger Body and is made up of PL/SQL
blocks.

!
What is a Trigger

The execution of trigger is transparent to User. Triggers are


executed by database when specific type of data manipulation
commands are performed on specific tables. Such command
may include inserts/updates/delete. Updates of specific
columns may also be used as triggering events.

After Oracle 8i, Shutdown/login events may also be used as


database triggering events.

!
Required system
privileges
To create a trigger on a table, you must be able to alter that
table. In addition, you must have CREATE TRIGGER
system privileges and to create trigger in another
account/schema, you should have CREATE ANY
TRIGGER system privileges.

To alter any trigger you must be owner of the trigger or have


the ALTER ANY TRIGGER system privileges.

!
What a Trigger is
Application
DATABASE • Triggering Events
– INSERT
INSERT
INTO EMP …; Table EMP INSERT – UPDATE
Trigger – DELETE
UPDATE EMP
SET …;
UPDATE
Trigger • Trigger Types
– Before/ After
DELETE
FROM EMP…; – Per Statement/
DELETE Per row
Trigger

!
@
Trigger
• A user-defined PL/SQL block associated with a
specific table, and implicitly fired (executed) when
a triggering statement is issued against the table.

Made up of 4 parts:
– Triggering event (INSERT/UPDATE/DELETE)
– Trigger type (BEFORE/AFTER, per statement / per row)
– Trigger restriction (optional) WHEN clause
– Trigger action PL/SQL block

!
Trigger
Example: Keeping salary in range for a job

CREATE OR REPLACE TRIGGER salary_check


BEFORE INSERT OR UPDATE OF sal, job
ON emp
FOR EACH ROW
WHEN ( NEW.job <> 'PRESIDENT')
DECLARE
minsal NUMBER;
maxsal NUMBER;

(Example continues to next page)

!
Trigger
BEGIN -- (Continuation of previous page)
/*Get min and max salaries for the*/
/* employee's job from the SAL_GUIDE*/
SELECT minsal, maxsal INTO minsal, maxsal
FROM sal_guide
WHERE job = :NEW.JOB;
/* If salary below min or above max, */
/* generate an error */
IF (:NEW.sal < minsal OR :NEW.sal > maxsal )
THEN raise_application_error (-20500,'Salary'
|| :NEW.sal
|| 'out of range for job'|| :NEW.job || 'for
employee'
||:NEW.ename);
END IF;
END;
/* End of trigger*/ !
Triggers v/s Stored
Procedures
Similarities
– Made up of PL/SQL and SQL statements.
– Use shared SQL areas.
– Cannot be changed (must be dropped and recreated).
– Dependencies tracked by ORACLE automatically.

Differences
– Triggers invoked implicitly; procedures invoked explicitly
– Triggers and procedures created with different SQL statements
– Triggers are associated with tables
– COMMIT, ROLLBACK, SAVEPOINT not allowed in triggers
(nor in procedures called by triggers)
!
@
Database v/s Forms
Triggers
• Database trigger
– Fires while statement executes.
– Fires independently of and in addition to Forms triggers.
– Fired by SQL statement from any tool or application.
– Can prevent completion of SQL statement.
– Fire as each statement is executed.
• Forms trigger
– Associated with particular form.
– Only executes when form is run.
– Can fire after each field is entered.
– Pre/post INSERT/UPDATE/DELETE triggers execute
when COMMIT key is pressed.
!
Creating a Trigger
Syntax:
CREATE [OR REPLACE] TRIGGER [schema.] trigger
{BEFORE/AFTER/INSTEAD OF}
{DELETE (OR)/UPDATE(OF column) (OR)/INSERT}
ON [schema.] table
[REFERENCING {OLD AS old(and) /NEW AS new}]
[FOR EACH ROW]
[WHEN (condition)]
pl/sql_block

Note: Triggers are stored separately from other objects,


so a trigger and a table could have the same name
(unique names recommended)
!
Types of Triggers
Type of a trigger determines
– The 'time' when the trigger fires
• BEFORE trigger(before the triggering action).
• AFTER trigger (after the triggering action)
• INSTEAD OF trigger(Instead of triggering action)
– The 'item' the trigger fires on
• Row trigger: once for each row affected by the triggering statement
• Statement trigger: once for the triggering statement, regardless of the
number rows affected
Each table can have up to 12 triggers in all:
– (INSERT/ UPDATE/ DELETE) *
– (BEFORE/ AFTER) *
– (STATEMENT/ ROW)
Types of Triggers:
Usage
BEFORE statement trigger
To initialise global variables used in triggers
To prevent update before it occurs (security, integrity)
BEFORE row trigger
To compute derived fields in the new row
To prevent updates before they occur
AFTER row trigger
For auditing (by value, by row)
Used by ORACLE snapshot mechanism
AFTER statement trigger
For auditing (audit after action takes place)
!
Trigger Firing
Sequence
1. INSERT, UPDATE, or DELETE trigger is applied to table
statement depending on the DML statement
2. Execute BEFORE statement trigger
3. For each row affected by the SQL statement:
a. Execute BEFORE row trigger
b. Change row and perform integrity constraint checking
c. Execute AFTER row trigger
4. Execute AFTER statement trigger
5. Complete deferred integrity constraint checking
6. Returns to application

Note: If a trigger statement fails, the entire triggering INSERT,


UPDATE, or DELETE is rolled back
!
Expressions in Triggers
• Referring to values in row triggers
To refer to the old and new values of a column in row triggers, use the
:OLD and :NEW prefixes:
IF :NEW.sal < : OLD.sal ...
• Notes:
– Values available in row triggers only
– New and old both available for UPDATE
– The old value in an INSERT is NULL
– The new value in a DELETE is NULL
– BEFORE row trigger can assign value to :NEW if it is not set
by UPDATE SET clause or INSERT VALUES list
– Can replace:NEW and :OLD with other correlation names if
desired (use REFERENCING clause)
– Colon dropped in WHEN clauses
!
Expressions in Triggers
• Conditional predicates
If a trigger can fire on more than one type of DML
operation, use pre-defined PL/SQL Boolean variables
to determine which caused the trigger to fire:
• IF INSERTING
• IF UPDATING
• IF DELETING
• To detect which column is being updated:
IF UPDATING ('column name')...

!
@
Expressions in Triggers
CREATE TRIGGER total_salary
AFTER DELETE OR INSERT OR UPDATE
OF deptno, sal ON emp
FOR EACH ROW BEGIN
/* assume DEPTNO, SAL are non-null */
IF (DELETING) OR (UPDATING AND
:OLD.deptno <> :NEW.deptno) THEN
UPDATE EMP
SET sal = sal - :OLD.sal
WHERE deptno = :OLD.deptno;
END IF;
IF (INSERTING) OR (UPDATING AND
:OLD.deptno <> :NEW.deptno) THEN
-- (Continued no next
page)
!
Expressions in Triggers
-- (Continuation of previous page)

UPDATE dept SET sal = sal + :NEW.sal


WHERE deptno = :NEW.deptno;
END IF;
IF (UPDATING) AND (:OLD.deptno = :NEW.deptno)
AND (:OLD.sal <> :NEW.sal) THEN
UPDATE dept
SET sal = sal + (:NEW.sal - :OLD.sal)
WHERE deptno = :OLD.deptno;
END IF;
END;

!
Restrictions on Triggers
Maximum number of 12 triggers for a table
Up to three (INSERT/UPDATE/DELETE) triggers of each type
Prohibited statements in triggers:
ROLLBACK
COMMIT
SAVEPOINT
Note: Also applies to procedures called by triggers (including
remote procedures)
Cascading trigger limit
The action of a trigger may cause another trigger to fire and so on
(called "cascading triggers')
Limit the depth of cascading with an INIT.ORA parameter
!
Restrictions on Triggers
• Mutating tables
– A table that is being modified by an UPDATE,
DELETE, or INSERT in a single user statement
– A trigger cannot SELECT from or change a mutating
table (except current row, using :NEW and :OLD)

• Changes to updated/inserted values


– A trigger cannot change values explicitly referenced in
the UPDATE statement SET clause or INSERT
statement

!
Enabling and Disabling
Triggers
Possible states for a trigger
• Enabled
– Executes its triggered action if both:
• an appropriate statement is issued
• trigger WHEN clause evaluates to TRUE (if present)
• Disabled
– Does not execute its triggered action

Note : Triggers are automatically enabled on creation

!
Enabling and Disabling
Triggers
• Reasons for disabling a trigger

• Have to load a large amount of data, and want to


proceed quickly without firing triggers
– Example: SQL*Loader using direct path automatically
disables triggers

• Want to INSERT, UPDATE, or DELETE on a


table whose trigger references a database object
that is not available
!
Enabling and Disabling
Triggers
With ALTER TRIGGER
ALTER TRIGGER [SCHEMA.]TRIGGER
ENABLE/DISABLE

Examples:
ALTER TRIGGER reorder DISABLE;
ALTER TRIGGER reorder ENABLE;

!
@
Enabling and Disabling
Triggers
With ALTER TABLE
ALTER TABLE [SCHEMA.]TABLE ENABLE/DISABLE
[ TRIGGER [SCHEMA.]TRIGGER | ALL TIRGGERS ]

Examples:
ALTER TABLE inventory DISABLE TRIGGER
reorder;
ALTER TABLE inventory ENABLE TRIGGER
reorder;
ALTER TABLE inventory DISABLE ALL
TRIGGERS;

!
Recompiling triggers

Syntax:
ALTER TIRGGER [SCHEMA.]TRIGGER COMPILE;

– Manually recompile to resolve dependencies (same as

procedures)

Example:
ALTER TRIGGER reorder COMPILE;

!
Dropping triggers

Syntax:
DROP TIRGGER [SCHEMA.]TRIGGER;

Example:
DROP TRIGGER reorder;

– Triggers cannot be altered


– They must be dropped and recreated

!
Triggers and Privileges
To create a trigger, creator must:
– Have CREATE TRIGGER system privilege
– One of the following:
• Own the table specified in the trigger statement ON clause
• Have ALTER privilege for the table specified in the trigger
statement ON clause
• Have ALTER ANY TABLE system privilege
To create a trigger in another schema, must:
– Have CREATE ANY TRIGGER system privilege

Note: A trigger fires with the privileges of its owner, not


the current user-owner must have appropriate access to
all objects referenced in the trigger action
!
Data Dictionary Views of
Triggers
Views:
USER_TRIGGERS
ALL_TRIGGERS
DBA_TRIGGERS
Fields
OWNER: owner of trigger (in DBA_TRIGGERS only)
NAME :name of trigger
TYPE:
BEFORE/AFTER
STATEMENT/ROW
EVENT: INSERT, UPDATE, and/or DELETE
TABLE_OWNER: owner of trigger's table
TABLE_NAME: name of trigger's table
WHEN: condition for trigger to fire
ENABLED: ENABLED or DISABLED
ACTION: action taken by trigger
!
Applications of Triggers

• Implementing Complex security rules


• Enforcing complex business rules
• Performing value-based auditing
• Making implied changes
• Maintaining table replication

!
Complex Security
Authorisation
Allows more complex security checking than
provided by ORACLE

Usage:
– Check for time of day, day of week
– Check for terminal being used
– Permit updates of certain amounts by specific users

!
@
Complex Security
Authorisation
CREATE TRIGGER emp_permit_changes
BEFORE INSERT OR DELETE
DECLARE dummy INTEGER;
BEGIN
/* Check for weekends */
IF (TO_CHAR(sysdate1 'DY') IN ('SAT','SUN')) THEN
raise_application_error(-20504, 'Cannot change
emp table during weekend');
END IF;
/* Check for company holiday*/
SELECT COUNT(*) INTO dummy
FROM temp
WHERE dairy = TRUNC(trans_date);
/* TRUNC removes time part of trans_date */
-- (Continued on next page)
!
Complex Security
Authorisation
-- (Continuation of pervious page)
IF dummy > 0 THEN
raise_application_error(-
205051
'Cannot change emp table during
holiday');
END IF;
/* Check for work hours (8am to 6pm) */
IF (TO_NUMBER(trans_date, 'HH24')NOT BETWEEN 8 AND
18) THEN
raise_application error (-2O5O6, 'Cannot
change emp table in off-hours');
END IF;
END; /* End of trigger*/

!
Enforcing Complex Business
Rules
Quick Notes
– Complex check constraints that are not definable using declarative
constraints
– Can be used to maintain data integrity across a distributed database
(declarative integrity cannot span distributed database)
– Note: Simple constraints are best handled by declarative constraint features

Example:
CREATE TRIGGER increase_chk
BEFORE UPDATE OF sal ON emp FOR EACH ROW
WHEN (NEW.sal < OLD.sal OR NEW.sal > 1.1 *
OLD.sal)
BEGIN
raise_application_error (-20502, 'May not
decrease salary Increase must be < 10% ');
END; !
Value-based Auditing

• Auditing that cannot be accomplished with standard


RDBMS auditing features
• Allows:
– Exclusively DML auditing
– Per row auditing
– Storage of update details
• Note: Many basic conditional auditing functions
accomplished best by standard RDBMS auditing
• Triggers cannot audit:
– DDL
– SELECT's
– Logons
!
Value-based Auditing

CREATE TRIGGER audit_trigger


BEFORE INSERT OR DELETE OR UPDATE
ON emp
FOR EACH ROW
BEGIN
IF INSERTING THEN
INSERT INTO temp(message)
VALUES (USER || ' is inserting' ||
' new name : ' || :new.ename );
END IF;
END;

!
Making Implied Changes
Table PENDING_ORDERS
PART_NO ORD_QTY ORD_DATE
00234 15 15-JAN-92
00342 25 15-JAN-92

Table INVENTORY
PART_NO ON_HAND REORD_PT
REORD_QTY
00234 34 30
15
00342 52 50
25

• Transparently perform an action when a


!
Implied Data Changes
Example: inventory check generates a new order
CREATE TRIGGER inv_check
AFTER UPDATE of on_hand
ON inventory FOR EACH ROW
WHEN (NEW.on_hand < NEW.reord pt)
DECLARE x NUMBER; /*dummy variable*/
BEGIN
/* query to see if part has been */
/ * reordered. Yes: X>= 1, no: x = 0*1
SELECT COUNT(*)
INTO x FROM pending_orders
WHERE pending_orders.part_no := :NEW.part_no;
IF x = 0 THEN
INSERT INTO pending_orders
VALUES(:NEW. part_no, :NEW.record_qty,
SYSDATE);
END IF;
!
Benefits of Triggers
• Security
– Allows sophisticated security checking
– Enables customised auditing mechanism to be built
• Integrity
– Ensures related operations on data are performed
together
– Can be used to enforce complex business rules
• Performance
– Reduces number of calls to the RDBMS
– Decreases network traffic

!
Benefits of Triggers
• Memory savings
– Takes advantage of shared SQL
– Requires only one copy of the code for
multiple users
• Productivity
– Requires only a single copy of code be written
and maintained (not multiple copies in client
applications)

!
Advantages of PL/SQL
PL/SQL is a completely portable, high-performance
transaction processing language that offers the
following advantages:

– support for SQL


– support for object-oriented programming.
– Better performance
– portability
– higher productivity
– integration with ORACLE

!
PL/SQL Native
Compilation

• Starting in Oracle9i Release 1, PL/SQL


program units can be compiled directly into
machine code.
– Stored procedures, functions, packages, types,
and triggers
• Alternatively, PL/SQL code can be
interpreted as in Oracle8i and earlier.
When PL/SQL Native Compilation
Occurs

• When you create or explicitly recompile a


PL/SQL program, the plsql_compiler_flags
instance parameter tells Oracle whether or
not to natively compile the code.
• This setting gets saved with the PL/SQL
program and used in the future in the event
of an implicit recompile.
Explicit vs. Implicit
Compilation
• Explicit compilation is where you tell Oracle to compile
a program unit:
– CREATE PACKAGE dbrx_util…
– CREATE OR REPLACE TRIGGER customers_t1…
– ALTER FUNCTION valid_email_address COMPILE;
• Implicit compilation is where Oracle needs to access a
PL/SQL program unit that has been invalidated. In this
case Oracle recompiles the program without being told
to do so.
How PL/SQL Code is Compiled

• When you compile PL/SQL into byte codes,


Oracle parses the code, validates it, and gen-
erates byte codes for interpretation at runtime.

• If plsql_compiler_flags is set to ‘native’, then


Oracle generates a C code source file instead of
the byte codes. The C code is compiled using
your C compiler, and linked into a shared
library callable by the oracle executable.
Thank you for your
Attention !

You might also like