Sie sind auf Seite 1von 167

PL/SQL Fundamentals

Prepared By

TATA CONSULTANCY SERVICES

PL/SQL

PL/SQL

PL/SQL is Oracle corporation's


procedural language extension to SQL,the standard data access language for RDBMS and ORDBMS

It brings state-of-the-art programming to the Oracle server and Tool set Contains all SQL DML functionality

PL/SQL

PL/SQL Architecture

PL/SQL runtime system is a technology,not an independent product. This technology is an engine that executes PL/SQL blocks and subprograms PL/SQL resides in two environments:
Oracle

server Oracle tools

PL/SQL engine accepts PL/SQL block or subprograms as input Engine executes procedural statements but sends SQL statements to SQL statement executor
PL/SQL 3

PL/SQL Architecture
PL/SQL block issued from:

Forms(Triggers) SQL*Plus Oracle Pre-compilers Oracle Call Interface (OCI)


PL/SQL engine located in:

Forms RDBMS

PL/SQL

Execution of a PL/SQL Block


Front-end OR Back-end Application portion APPLICATION / Pro*(C/ C++/ COBOL)/ Forms/ Reports Embedded PL/SQL BLOCK DECLARE Procedural BEGIN Procedural SQL Procedural SQL END; Host language Host language Host language Embedded PL/SQL BLOCK DECLARE Procedural BEGIN Procedural SQL Procedural SQL END; Oracle Server

PL/SQL Statement Executor

SQL Statement Executor

PL/SQL

PL/SQL Block
DECLARE (Declaration Section)

PL/SQL is block-structured language.

The basic units that make up a


PL/SQL programs are logical blocks

BEGIN (Executable Section)

Typically,each logical block corresponds to a problem or subproblem to be solved.

EXCEPTION (Exception Handler Section)

PL/SQL

PL/SQL Block Structure


Declaration Section Executable Section Exception Handler Section Quick Notes - Block Structuring
Any

block may contain sub-blocks. Sub blocks may appear anywhere in an executable statement. Statements end with a ; Comments
are

preceded by -- for inline comments or surrounded by /* */


Declared

objects exist within a certain scope.


PL/SQL 7

Variable Declarations Overview


Syntax
Identifier [CONSTANT] datatype

[NOT NULL] [:= plsql_expression] Quick Notes:


The

rules for identifiers are the same as for SQL objects. NOT NULL may be used to constrain a variable so that it cannot have the null value. Only one identifier per line is allowed. E.g. DECLARE
firstname, lastname CHAR(2); -- illegal DECLARE firstname CHAR(20) NOT NULL; -- legal lastname CHAR(20) NOT NULL; -- legal
PL/SQL 8
@

Variable Declarations Overview

Two types of Declarations


Constant Variable

Data types(subtypes)
Number

(decimal,integer,real,smallint,nume ric) CHAR (character) DATE Boolean LOB (blob,clob.nclob,bfile)


PL/SQL 9

Declaration with Attributes

PL/SQL variables and cursors have attributes, which are properties that let you reference the datatype and structure of an item without repeating its definition. Database columns and tables have similar attributes, which you can use to ease maintenance. %TYPE Example books_printed NUMBER(6); books_sold books_printed%TYPE; maiden_name emp.ename%TYPE; %ROWTYPE Example dept_row dept%ROWTYPE:
PL/SQL 10

Variable Assignment

PL/SQL Expressions consist of Variables, Constants, Literal, and Function Calls.

Syntax:
plsql_ variable

:=

plsq1_expression;

Quick Notes :
:=

(ASSIGNMENT) = (VALUE EQUALITY) The datatype on the left and right side of an assignment must be the same or implicitly convertible to each other.
N := '7' -- legal
Column

or table references are not allowed on either side of the assignment operator (:=).
SCOTT.EMP.EMPNO := 1234; PL/SQL location := dept.loc; -- illegal.
11
@

Variable Assignment
N1 B1 D1 C1 N1 := 5 * N2 * 0.7; := TRUE; := '11-JUN-97'; := NULL; := SQRT( N2 ** 2 4 * N3 * N4);

Note:

Nn is Number type Bn is Boolean Cn is Char type Dn is Datetype


PL/SQL 12

Scope of Variables and Constants


SCOPE refers to the visibility of identifiers at different points in the PL /SQL block RULES:

1. An identifier is visible in the block in which it is declared and all its sub-blocks unless rule #2 applies. 2. if an identifier declared in an enclosing block is re-declared in a sub-block, the original identifier declared in the enclosing block is no longer visible in the sub-block However, the newly declared identifier has the rules of scope defined in rule #1.
PL/SQL 13

Scope of Variables and Constants


DECLARE a char; b number; BEGIN --identifiers available here : a(char),b DECLARE a integer ; c number; BEGIN -- identifiers available here : a (integer),b,c END; DECLARE d number; BEGIN --identifiers available here : a(char),b,d END; --identifiers available here : a (char),b END;
PL/SQL 14

SQL in PL / SQL

SQL Data Manipulation Language statement support


INSERT, UPDATE, DELETE, SELECT

Quick Notes:
The

full Oracle syntax is supported for these statements. A PL/SQL variable may be placed anywhere a construct may be legally placed. An identifier is first checked to see if it is a column in the database. If not, it is assumed to be a PL/SQL identifier.

PL/SQL

15

SQL in PL / SQL
Example: INSERT
DECLARE my_sal NUMBER(7, 2) := 3040.55; my_ename CHAR(10) := 'WANDA'; my_hiredate DATE := '08-Sep-88'; BEGIN INSERT INTO emp (empno, ename, job, hiredate, sal, deptno) VALUES (2741, my_ename, 'Cabie', my_hiredate, my_sal, 20); END;
PL/SQL 16
@

SQL in PL / SQL
Example: UPDATE
DECLARE max _allowed 5000; CONSTANT NUMBER :=

BEGIN
UPDATE emp SET sal = max_allowed

WHERE empno = 7934; END;

PL/SQL

17

SQL in PL / SQL
Example: DELETE

BEGIN DELETE FROM WHERE deptno END;

emp = 10 ;

PL/SQL

18

SQL in PL / SQL
SELECT

Syntax
SELECT col1, col2,.,. into var1,var2 FROM table name WHERE Quick Notes:
A

SELECT statement is the only DML that returns data. You must provide a location for this data to be stored via the INTO clause. A SELECT...INTO statement must return exactly one row. Zero or multiple returned rows results in an error. For multi-row SELECT's use cursors (discussed later).
PL/SQL 19

SQL in PL / SQL
Example: SELECT
DECLARE part_name parts.name%TYPE;

num_in_stock
BEGIN SELECT name, num

parts.num%TYPE;

INTO part_name,

num_in_stock
FROM parts WHERE part_id = 624; --manipulate the retrieved data here--

END;

PL/SQL

20

SQL in PL / SQL
Functional support

within a SQL Statement:


Numeric (e.g. SQRT, ROUND, POWER) Character (e.g. LENGTH, UPPER) Date (e.g. ADD_MONTHS, MONTHS_BETWEEN) Group (e.g. AVG, MAX, COUNT) INSERT INTO emp (ename) VALUES (UPPER(ename));

outside of a SQL Statement:


x := SQRT(y); lastname := UPPER(lastname); agediff := MONTHS_ BETWEEN(bday1, bday2)/12;

Note: Most of the SQL functions are available except the group functions.

PL/SQL

21

Execute Immediate Command

Provides a Native SQL command that greatly simplifies working with SQL statements. This applies to DDL, dynamic SQL, dynamic PL/SQL, and dynamic SELECT statements.

PL/SQL

22

Execute Immediate Command


Use EXECUTE IMMEDIATE for all New Code Re-Write DBMS_SQL if Time Permits or Issues EXECUTE IMMEDIATE Command Accepts Any SQL Command Exception: SELECT Retrieving Multiple Records Accepts Bind Variables with the USING Clause Allows Dynamic PL/SQL Creation

PL/SQL

23

Execute Immediate Command

Example 1: DDL Commands


Turning

TRACE On Changing the SORT AREA SIZE


DECLARE lv_sql_txt VARCHAR2(200); BEGIN EXECUTE IMMEDIATE 'ALTER SESSION SET SQL_TRACE=TRUE'; lv_sql_txt := 'ALTER SESSION SET SORT_AREA_SIZE = 1000000'; EXECUTE IMMEDIATE lv_sql_txt; END; /

PL/SQL

24

Execute Immediate Command

Example 2: Dynamic SQL Command


Current

Count of All Tables of Schema

DECLARE lv_count_num PLS_INTEGER:=0; CURSOR cur_counts IS SELECT table_name FROM user_tables ORDER BY table_name; BEGIN FOR cur_counts_rec IN cur_counts LOOP EXECUTE IMMEDIATE 'SELECT COUNT(*) FROM ' || cur_counts_rec.table_name INTO lv_count_num; DBMS_OUTPUT.PUT_LINE('Table Name: ' || RPAD(cur_counts_rec.table_name, 15) || ' Rows: ' || lv_count_num); END LOOP; END;

PL/SQL

25

Execute Immediate Command

Example 2: Dynamic SQL Command (Output) Current Count of All Tables of Schema
Name: Name: Name: Name: Name: S_CUSTOMER S_DEPARTMENT S_EMPLOYEE S_IMAGE S_INVENTORY Rows: Rows: Rows: Rows: Rows: 15 12 25 19 114

Table Table Table Table Table

PL/SQL procedure successfully completed.

PL/SQL

26

Execute Immediate Command

Example 3: DML Command Using Bind Variable


Updates

Salaries by 10 Percent

DECLARE lv_salary_increase NUMBER := .10; BEGIN EXECUTE IMMEDIATE 'UPDATE s_employee SET salary = NVL(salary, 0) * (1 + :increase)' USING lv_salary_increase; END; /

PL/SQL

27

Transaction Processing

Definition
ROLLBACK SAVEPOINT MARKER A (ROLLBACK TO) SAVEPOINT MARKER B (ROLLBACK TO)

SAVEPOINT MARKER C (ROLLBACK TO)


COMMIT

Syntax
SAVEPOINT < marker_name >; ROLLBACK [WORK] TO [SAVEPOINT] < marker_name >;
PL/SQL 28

Transaction Processing
BEGIN INSERT INTO temp(num,des)VALUES (1, 'row 1'); SAVEPOINT A; INSERT INTO temp (num,des) VALUES 2'); SAVEPOINT B; INSERT INTO temp (num,des) VALUES 3'); SAVEPOINT C; ... ROLLBACK TO SAVEPOINT B; COMMIT; END;
PL/SQL 29

(2,

'row

(3,

'row

Control Structures

Conditional: Iterative: Sequential:

IF statements LOOP and EXIT statements GOTO and NULL statements

F T F T

Condition

Iteration
PL/SQL

Sequence
30

Conditional Control

Condition:

Logical Comparisons form the basis of conditional control in PL/SQL; the results of these comparisons are always either TRUE, FALSE or NULL. Quick Notes: Anything compared with NULL results in a NULL value. A NULL in an expression evaluates to NULL(except concatenation). Eg. 5 + NULL -- evaluates to NULL
'PL'||NULL||'/SQL' -- evaluates to PL/SQL

PL/SQL

31

Conditional Control: IF

To conditionally execute a statement or sequence of statements.

Syntax
If <condition> THEN

<sequence
[ELSIF

of statements> of statements>]

<condition> THEN

<sequence
[ELSE

-- ELSIFs may be repeated

<sequence
END IF;

of

statements>]
PL/SQL 32

Conditional Control: IF
DECLARE num_jobs NUMBER (7); actor_id actor.actorid%type; BEGIN actor_id := &actor_id; SELECT COUNT(*) INTO num_jobs FROM auditions WHERE actorid = actor_id AND called_back = 'YES'; IF num_jobs > 40 THEN UPDATE actor SET actor_rating = 'OSCAR time' WHERE actorid = actor_id; ELSIF num_jobs > 20 THEN UPDATE actor SET actor_rating = 'daytime soaps' WHERE actorid = actor_id; ELSE UPDATE actor SET actor_rating = 'waiter' where actorid = actor_id; END IF; COMMIT; END;

PL/SQL

33

Iterative Control

Loops repeat a statement or sequence of statements multiple times.

Four types of loops: I. Simple loops 2. Numeric FOR Loops 3. WHILE Loops 4. Cursor FOR loops

PL/SQL

34

Iterative Control: LOOP and EXIT

Simple Loops repeat a sequence of statements multiple times.

Syntax
LOOP <sequence of statements> END LOOP; -- sometimes called an 'infinite' loop

Exit Statements exit any type of loop immediately and program control goes to the immediate statement after the loop

Syntax
EXIT WHEN <condition> ; -- 'infinite' loop insurance
PL/SQL 35

Iterative Control: LOOP and EXIT


DECLARE ctr NUMBER(3) :=0;

BEGIN
LOOP INSERT INTO temp(num,des) VALUES (ctr,'ITERATION COMPLETE'); ctr := ctr+1; IF ctr = 500 THEN EXIT; END IF; END LOOP; END;

PL/SQL

36

Iterative Control: FOR

Numeric FOR Loops repeat a sequence of statements a fixed number of times.

Syntax

FOR <index> IN [ REVERSE ]<integer>..<integer> LOOP <sequence of statements>


END LOOP; Quicknotes - Index:

The Loop Index takes on each value in the range, one at a time, either in forward or reverse order It is implicitly of type NUMBER. It is only defined within the loop. Value may be referenced in an expression, but a new value may not be assigned to it within the loop
PL/SQL 37

Iterative Control: FOR


Example1
BEGIN FOR I IN 1..500 LOOP INSERT INTO temp (message) VALUES ('I will not sleep in class.'); END LOOP; END;

Example2
DECLARE my_index CHAR(20) := Hello' BEGIN FOR my_index IN REVERSE 21...30 LOOP /* redeclares my index */ INSERT INTO temp (des) VALUES (my_index); /* inserts the numbers 30 through 21 END LOOP; END;
PL/SQL

*/

38

Iterative Control: WHILE

WHILE Loops repeat a sequence of statements until a specific condition is no longer TRUE.

Syntax
WHILE <condition> LOOP <sequence of statements> END LOOP;

Quick Notes:
The

term <condition> may be any PL/SQL condition (I.e., it must return a BOOLEAN value of TRUE, FALSE, or NULL). The sequence of statements will be repeated as long as <condition> evaluates to TRUE.
PL/SQL 39

Iterative Control: WHILE


DECLARE ctr NUMBER (3) := 0; BEGIN WHILE ctr < 500 LOOP INSERT INTO temp (message)

VALUES ('Well, might sleep just a little'); ctr := ctr + 1;


END LOOP; END;

PL/SQL

40

Sequential Control: NULL

It does nothing other than pass the control to the next statement

Syntax
NULL;

Quick Notes:
NULL

statement and the Boolean non-value NULL are different Make use of NULL in the IF condition for doing nothing in any branch of the condition
PL/SQL 41

Sequential Control: NULL


Example1: Minimum PL/SQL block
BEGIN NULL; END;

Example2: Use in IF statement


BEGIN IF <condition> THEN Statements ELSIF <condition> THEN NULL; -- do nothing branch of the IF statement ELSE Statements ENDIF; END;

PL/SQL

42

Sequential Control: GOTO

GO TO Statements jump to a different place in the PL/SQL block .

Syntax
<<label_name>> x:=x + 1; -- a statement label GOTO label_name; -jumps to x := x + 1 GOTO

GO TO Statements have 2 parts

A statement with the label: where you want control to come back using GO TO statement somewhere else in the program

A statement with GO TO: to make control jump to the label.


PL/SQL 43

Sequential Control: GOTO

Quick Notes:

You can only legally GOTO a statement that is either: 1. in the same sequence of statements as the GOTO statement

2 . In the sequence of statements that encloses the GOTO statement (i.e an outer block)
BEGIN

<<Come_here>> X := X + 1;
... Statements -- to the label Come_here END;
PL/SQL 44

GOTO Come_here;-- Now control will jump back

Other Uses for Statement Labels


Labels may label any statement In addition to their use as targets for GOTO statements, labels may be used for:

1. Blocks 2. Loops

Labelling a block and loop allows referencing of DECLARED objects that would otherwise not be visible because of scope rules.
Labelling a loop also allows control to exit in outer loops

PL/SQL

45

Other Uses for Statement Labels


Example1:
BEGIN <<sample>> DECLARE deptno NUMBER :=10; BEGIN DECLARE deptno NUMBER := 20; BEGIN UPDATE emp SET sal = sal * 1.1 WHERE deptno = sample.deptno; COMMIT; END; END sample; END;

PL/SQL

46

Other Uses for Statement Labels


Example2:
compute_loop FOR i IN 1..100 LOOP <statements> DECLARE I NUMBER := 0; BEGIN INSERT INTO temp (num,des) VALUES (compute_loop.i, 'COMPLETE'); END ; END LOOP compute_loop; -- must include loop name here

PL/SQL

47

Other Uses for Statement Labels


Example3:
outer loop

WHILE a >b LOOP


b:= b +1; inner loop WHILE b > c LOOP C := C + 2; EXIT outer_loop WHEN c > 200; -- break END LOOP inner loop;

END LOOP outer_loop;

PL/SQL

48

User Defined Records

User defined records,unlike,%ROWTYPE attribute provide the flexibility of specifying the datatypes of fields and defining the fields of your own Records like PL/SQL are declared in two steps

Declare Record type


TYPE type_name IS RECORD (field_name1 {field_type | variable%TYPE | table.column%TYPE | table%ROWTYPE} [NOT NULL], field_name2 {field_type | variable%TYPE | table.column%TYPE | table%ROWTYPE} [NOT NULL], ...)

Declare Record of that type record_name type_name;


PL/SQL 49
@

User Defined Records

Unlike PL/SQL tables ,Records have uniquely defined field name and a record can be initialized in its declaration To reference individual fields in a record,you use dot notation record_name.field_name Assigning value to a field in record record_name.field_name := plsql_rec

PL/SQL

50

User Defined Records


DECLARE TYPE DeptRectyp is RECORD(deptno number(2),dname char(14),loc char(13)); dept_rec DeptRectyp; .. BEGIN SELECT deptno ,dname,loc into dept_rec FROM dept WHERE deptno = 30; .. END;

PL/SQL

51

PL/SQL Tables

PL/SQL tables declared in two steps

Define table type


TYPE type_name IS TABLE OF {column_type | variable%type table.column%type} [NOT NULL] INDEX BY BINARY_INTEGER;
|

Declare PL/SQL table of that type


plsql_table_name

type_name;

To reference rows in a PL/SQL table , specify index value using the array like syntax
plsql_table_name(index value) E.g.:ename_tab(3);

PL/SQL

52

PL/SQL Tables
DECLARE TYPE EnameTabTyp IS TABLE OF emp.ename%TYPE INDEX BY BINARY_INTEGER; TYPE SalTabTyp IS TABLE OF emp.sal%TYPE INDEX BY BINARY_INTEGER; ename_tab EnameTabTyp; sal_tab SalTabTyp; I BINARY_INTEGER := 0; ...

(Continued on next page)

PL/SQL

53

PL/SQL Tables
BEGIN --load employee name and salaries into PL/SQL tables FOR emprec IN (SELECT ename,sal from emp) LOOP I := I +1; ename_tab(I) := emprec.ename; sal_tab(I) := emprec.sal; END LOOP; -- process the tables process_sals(ename_tab,sal_tab); .. END;

PL/SQL

54

Cursor

A work area to execute SQL statements and store processing information. Every SQL DML statement processed by PL/SQL has an associated CURSOR. Two Types of CURSORS
1.

EXPLICIT
Multiple row SELECT Statements

2.

IMPLICIT

All INSERT Statements All UPDATE Statements All DELETE Statements Single row SELECT....INTO Statements
PL/SQL 55
@

Explicit Cursor:

Use

STEP 1. Declare the cursor

Syntax:
DECLARE CURSOR <cursor name> IS <regular select: statement>;

Quick Notes:
The

<regular select statement> must NOT include the INTO clause in a single-row SELECT...INTO statement Declared cursors are scoped just like variables.
PL/SQL 56

Explicit Cursor:
Example:

Use

DECLARE x NUMBER(7,2); total NUMBER(5); lower_sal_limit CONSTANT NUMBER(4) := CURSOR c1 IS SELECT ename FROM emp WHERE sal > lower_ sal _limit; BEGIN

1200;

STEP 2. Open the cursor

Syntax:
OPEN <cursor name>; -- excecutes the query and identifies the result set consisting of all the rows that meet the query criteria.
PL/SQL 57
@

Explicit Cursor:

Use

STEP 3. Fetch data from the cursor

Syntax:
FETCH <cursor name> into <var1, var2..>; -- fetches values to the variable and increments the pointer to the next value.

Quick Notes:

Retrieves one row of data from the cursor, and stores it in the specified variables (similar to how a single-row SELECT works). There must be exactly one INTO variable for each column selected by the SELECT statement. The first column gets assigned to var1, the second assigned var2, etc.

PL/SQL

58

Explicit Cursor: Use

STEP 4. Close the cursor

Syntax:
CLOSE <cursor name>; -- closes the cursor , and the result set becomes unidentified ( NOTE: Once a cursor is closed ,it can be reopened . Any other operation on a closed cursor raises predefined exception INVALID_CURSOR.)

PL/SQL

59

Explicit Cursor: Attributes

%NOTFOUND
LOOP FETCH my_cursor INTO my_ename, my_sal; EXIT WHEN my_cursor%NOTFOUND; --process data here END LOOP;

%FOUND
FETCH WHILE -FETCH my_cursor INTO my_ename, my_ sal; my_cursor%FOUND LOOP process data here my_cursor INTO my ename, my_sal;

END LOOP;
PL/SQL 60

Explicit Cursor: Attributes

%ROWCOUNT
LOOP FETCH my_cursor INTO my_ename, my_sal; EXIT WHEN (my_cursor%NOTFOUND) OR (my_cursor%ROWCOUNT> 10); --process data here

END LOOP;

%ISOPEN
IF my_cursor%ISOPEN THEN FETCH my_cursor into my_ename,my_sal; ELSE OPEN my_cursor; END IF;
PL/SQL 61
@

Explicit Cursor
Example: Reopening a cursor DECLARE total_bonus NUMBER(8,2) min _sal := 0;

emp.sal%TYPE := 1000; -- start guessing bonus_ amt emp . sal%TYPE; CURSOR bonus IS SELECT sal *.10 FROM emp WHERE sal > min_ sal;

(Continued on next page)

PL/SQL

62

Explicit Cursor
Example: Reopening a cursor BEGIN -- (Continued from previous page) OPEN bonus; -- uses min_ sal value of 1000 LOOP FETCH bonus INTO bonus_amt; EXIT WHEN bonus%NOTFOUND; total_bonus := total_bonus + bonus_amt; IF total_bonus > 2000 THEN /* up the minimum and try again */ min_sal :=min_sal + 500; total_bonus := 0; -- reset the total close bonus; OPEN bonus; -- re-open with new min _sal END IF; END LOOP; --you may want to store min_sal somewhere CLOSE bonus; END;
PL/SQL 63
@

Explicit Cursor: FOR loops

Cursor FOR Loops specify a sequence of statements to be repeated once for each row that is returned by the cursor.

Syntax
FOR <record_name> IN <cursor_name> LOOP -statements to be repeated go here END LOOP;

Numeric FOR Loop Similarities


Specify a Set of rows from a table by using the cursor's name v/s. Specifying a set of integers (i.e. 1..10) Index takes on the values of each row v/s index taking on integer values (i.e. 1 through 10).
PL/SQL 64

Explicit Cursor: FOR loops


Conceptual Cursor Loop Model LOOPS: When a cursor loop is initiated, an implicit OPEN cursor_name is executed.
For

each row that satisfies the query associated with the cursor, an implicit FETCH is executed into the components of record_name.

when

there are no more rows left to FETCH, an implicit CLOSE cursor_name is executed and the loop is exited.
PL/SQL 65

Explicit Cursor: FOR loops


DECLARE sal_limit NUMBER(4) := 0; total_sal NUMBER(9,2):=0; CURSOR my_cursor IS SELECT ename,sal FROM emp WHERE sal > sal_limit; BEGIN sal_limit := 1200; FOR cursor_row IN my_cursor LOOP INSERT INTO temp(message,num) VALUES (cursor_row.ename, cursor_row.sal); total_sal := total_sal + cursor_row.sal; END LOOP; COMMIT; END;

PL/SQL

66

Implicit Cursor

An Implicit Cursor is automatically associated with any SQL DML statement that does not have an explicit cursor associated with it.
INSERT,

UPDATE , DELETE, SELECT...INTO

Quick Notes:
Implicit

cursor is called the "SQL'' cursor - it stores information concerning the processing of the last SQL statement not associated with an explicit cursor OPEN, FETCH, and CLOSE don't apply. All cursor attributes apply.
PL/SQL 67
@

Implicit Cursor: Attributes

SQL %NOTFOUND
UPDATE emp SET sal = sal*10.0 WHERE ename = 'WARD'; IF SQL%NOTFOUND THEN -- WARD wasn't found INSERT INTO emp(empno, ename, sal) VALUES (4, 'WARD', 9999); END IF;

SQL %FOUND SQL%ROWCOUNT


DELETE FROM baseball_team WHERE batting_avg< . 100; IF SQL%ROWCOUNT > 5 THEN INSERT INTO temp (message) VALUES ('Your team needs help.') END IF;

SQL%ISOPEN

(always evaluates to FALSE)


PL/SQL 68
@

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

PL/SQL

69

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.
PL/SQL 70

Exceptions: Predefined Internal

TOO_MANY_ROWS

(ORA -01427)

a single row SELECT returned more than one row

NO_DATA_FOUND
INVALID CURSOR

(ORA -01403)
(ORA-01001)

a single row SELECT returned no data

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
PL/SQL 71
@

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>
PL/SQL 72

Exception Handlers
DECLARE

employee_num
BEGIN

emp.empno%TYPE;

SELECT empno INTO employee_num FROM emp WHERE ename = 'BLAKE';

INSERT INTO temp


VALUES (NULL, employee_num, 'BLAKE's number.'); DELETE FROM emp WHERE ename = 'BLAKE'; --(Continued on next page) employee

PL/SQL

73

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;

PL/SQL

74

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

your exception

RAISE my_exception;
PL/SQL 75

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.


PL/SQL 76

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;
PL/SQL 77

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).
PL/SQL 78

Exception: Propagation
BEGIN . BEGIN IF X = 1 THEN RAISE A; ELSIF X=2 THEN RAISE B; ELSE RAISE C;

EXCEPTION WHEN A THEN END;

EXCEPTION WHEN B THEN END;

Exception A: Is handled locally in the inner block and execution resumes in the outer block. Exception B: Propagates to the first outer block with an appropriate handler Is handled in the outer block and control is passed back to the calling environment Exception C: Has no handler and will result in a runtime unhanded exception

Calling Environment
PL/SQL 79

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.


PL/SQL 80

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
PL/SQL 81

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;

PL/SQL

82

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);
PL/SQL 83
@

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
PL/SQL 84
@

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

PL/SQL

85

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;

PL/SQL

86

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
PL/SQL 87

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
PL/SQL 88

Uses for procedures

Define central well-known business functions


Create

an order Delete a customer

Store batch job in the database


Weekly

account rollups and process information from remote

Encapsulate a transaction
Gather

nodes

Funnel activity on a table through a single path


All

changes to employee salaries should change department budgets


PL/SQL 89

Creating a Procedure
Syntax:
CREATE OR REPLACE PROCEDURE [ schema.] procedure argument [ IN ] [OUT ] [ INOUT ] datatype [ IS ] [ AS ] pl/sql_subprogram_body

PL/SQL

90

Creating a Procedure
Argument modes IN
Data

value comes in from the calling process and is not changed (the default)
data value comes in from the calling process; on normal exit (no error), value of argument is passed back to caller

OUT
No

IN OUT

Data value comes in from the calling process, and another value is returned on normal exit
PL/SQL 91
@

Creating a Procedure
Example
CREATE PROCEDURE fire_employee (empid NUMBER) BEGIN .... DELETE FROM emp WHERE empno = fire_employee.empid; END; AS

Tip: Write each procedure in a text file, and save (both P-code(Parsed Code) and source code is saved in the database)
PL/SQL 92

Creating and Changing a Function


Syntax:
CREATE OR REPLACE [ schema.] function FUNCTION

(argument datatype ) RETURN datatype [ IS ] [ AS ] subprogram_body

Note: Every function must return a value of the


specified type using RETURN statement
PL/SQL 93

Creating and Changing a Function


Example:
CREATE FUNCTION get_sal (emp_no NUMBER) RETURN NUMBER IS emp_sal NUMBER (11,2); BEGIN SELECT sal INTO emp_sal FROM emp WHERE empno =

emp_no;

RETURN (emp_sal); END;


PL/SQL 94

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

PL/SQL

95

Dropping a Procedure
Example:
DROP PROCEDURE fire_employee;

Marks dependent objects for recompilation

PL/SQL

96

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


PL/SQL 97
@

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);

PL/SQL

98

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
PL/SQL 99

Privileges for Procedures


PROCEDURE system privileges apply to packages, procedures, functions.
To Do this CREATE Need Either Create procedure or Create any procedure System privilege Own the procedure or ALTER ANY PROCEDURE system privilege Own the procedure or DROP ANY PROCEDURE system privilege Own the procedure or be granted EXECUTE PRIVILEGE or EXECUTE ANY PROCEDURE system privilege Procedure owner must be explicitly granted access to all database objects in the procedure (not through roles) And Owner must have access to all objects referenced in the procedure

ALTER DROP Execute a procedure or access a package construct

PL/SQL

100

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

101

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

102

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. Note: User needs to reissue CREATE statement

PL/SQL

103

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

PL/SQL

104

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

PL/SQL

105

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

PL/SQL

106

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 PL/SQL

107

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 REFERENCED_NAME: Owner of parent object referenced_TYPE: Type of parent object REFERENCED_LINK_OWNER: Owner of remote link (if used) REFERENCED_LINK_NAME: Name of remote link (if used) REFERENCED_TIMESTAMP: when parent was last compiled ORDER_NUMBER: Level of PL/SQL dependency

108

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


PL/SQL 109

Dependencies and Procedures


Procedure P Table T Indirect dependency

View of T Direct dependency Direct dependency

PL/SQL

110

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
PL/SQL 111

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

PL/SQL

112

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

PL/SQL

113

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;

PL/SQL

114

Benefits of Procedures

Security Executes under security domain of procedure's owner Provides controlled indirect access to database objects to nonprivileged users Integrity Defines allowed operations on data Ensures related actions are performed together

PL/SQL

115

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

PL/SQL

116

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

PL/SQL

117

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)

PL/SQL 118

Parts of a Package

Package specification

Declares (specifics) package constructs, including names and parameters of publicly available procedures and functions 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

Package body

PL/SQL

119

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
PL/SQL 120

Public and Private Package Constructs


Public declarations
PACKAGE hire_fire IS PROCEDURE hire_employee (..); PROCEDURE fire_employee(..); valid CHAR(1); END; PACKAGE BODY hire_fire IS PROCEDURE hire_employee(..) IS BEGIN.. END; PROCEDURE hire_employee(..) IS BEGIN.. END; FUNCTION check_num(..) RETURN.. BEGIN.. END; END; IS

Definition of public constructs

Definition of private function

PL/SQL

121

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

PL/SQL

122

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

PL/SQL

123

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;

PL/SQL

124

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;

PL/SQL

125

Dropping Packages
Syntax:
DROP PACKAGE [schema.] package

Example:
DROP PACKAGE hire_fire;

Drops

both package specification and

body Marks for recompilation any

dependent objects

PL/SQL

126

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;
PL/SQL 127

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.

PL/SQL

128

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
PL/SQL 129

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
PL/SQL 130

Triggers

What a trigger is 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
PL/SQL 131

What a Trigger is
Application INSERT INTO EMP ; Table EMP DATABASE

Triggering Events

INSERT Trigger

INSERT UPDATE DELETE

UPDATE EMP SET ;

UPDATE Trigger

Trigger Types

DELETE FROM EMP;

Before/ After Per Statement/ Per row

DELETE Trigger

PL/SQL

132

What a Trigger is

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

PL/SQL

133

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)

PL/SQL

134

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*/
PL/SQL 135

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)
PL/SQL 136
@

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.

PL/SQL

137

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)
PL/SQL 138

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)
PL/SQL 139
@

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)
PL/SQL 140

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
PL/SQL 141

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

PL/SQL

142

Expressions in Triggers

Conditional predicates

If a trigger can fire on more than one type of DML operation, use predefined PL/SQL Boolean variables to determine which caused the trigger to fire:
INSERTING IF UPDATING IF DELETING To detect which column is being updated:
IF

IF UPDATING ('column name')...


PL/SQL 143
@

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 DEPT SET totalsal = totalsal - :OLD.sal WHERE deptno = :OLD.deptno; END IF; IF (INSERTING) OR (UPDATING AND :OLD.deptno <> :NEW.deptno) THEN -- (Continued no next page)

PL/SQL

144

Expressions in Triggers
-- (Continuation of previous page) UPDATE dept SET totalsal = totalsal + :NEW.sal WHERE deptno = :NEW.deptno; END IF; IF (UPDATING) AND (:OLD.deptno = :NEW.deptno) AND (:OLD.sal <> :NEW.sal) THEN UPDATE dept SET totalsal = totalsal + (:NEW.sal :OLD.sal) WHERE deptno = :OLD.deptno; END IF; END;

PL/SQL

145

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

PL/SQL

146

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

PL/SQL

147

Enabling and Disabling Triggers


Possible states for a trigger Enabled
Executes
an

its triggered action if both:

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


PL/SQL 148

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

PL/SQL

149

Enabling and Disabling Triggers


With ALTER TRIGGER
ALTER TRIGGER [SCHEMA.]TRIGGER ENABLE/DISABLE

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

PL/SQL

150

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;

PL/SQL

151

Recompiling triggers
Syntax:
ALTER TIRGGER [SCHEMA.]TRIGGER COMPILE;

Manually

recompile to resolve

dependencies (same as

procedures)
Example:

ALTER TRIGGER reorder COMPILE;


PL/SQL 152

Dropping triggers
Syntax:
DROP TIRGGER [SCHEMA.]TRIGGER;

Example:
DROP TRIGGER reorder;
Triggers

cannot be altered They must be dropped and recreated

PL/SQL

153

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 Have CREATE ANY TRIGGER system privilege

To create a trigger in another schema, must:

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
PL/SQL 154

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 PL/SQL

155

Applications of Triggers

Implementing Complex security rules Enforcing complex business rules Performing value-based auditing Making implied changes Maintaining table replication

PL/SQL

156

Complex Security Authorisation


Allows more complex security checking than provided by ORACLE Usage:
Check

for time of day, day of week

Check
Permit

for terminal being used


updates of certain amounts by specific

users

PL/SQL

157

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)

PL/SQL

158

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*/

PL/SQL

159

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;

PL/SQL

160

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
PL/SQL 161

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;

PL/SQL

162

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_QTY 00234 34 00342 52

REORD_PT 30 50 15 25

Transparently perform an action when a triggering statement is executed


PL/SQL 163

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; END;
PL/SQL 164

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


PL/SQL 165

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)

PL/SQL

166

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

167

Das könnte Ihnen auch gefallen