Download as pdf or txt
Download as pdf or txt
You are on page 1of 173

PL/SQL Basic Concepts

Prerequisites

Prior knowledge of Oracle database

Prior knowledge of DDL, DML & SQL Language

Oracle 9i/10g installation on trainee desktop

SQL*Plus utility installed

Editor Notepad / Wordpad

2003 Accenture All Rights Reserved. 2


Introduction

PL/SQL stands for Procedural Language/SQL

PL/SQL extends SQL by adding constructs found in procedural


languages, resulting in a structural language that is more powerful
than SQL

PL/SQL is a modern, block-structured programming language

PL/SQL provides several features that make developing powerful


database applications very convenient

The basic unit in PL/SQL is a block. All PL/SQL programs are


made up of blocks, which can be nested within each other

2003 Accenture All Rights Reserved. 3


Introduction

PL/SQL blocks can have both SQL data manipulation language


(DML), and data definition language (DDL) statements

PL/SQL provides procedural constructs, such as loops and


conditional statements, that are not available in standard SQL

PL/SQL offers features such as Data Encapsulation, Exception


Handling, Information Hiding, Object Orientation

2003 Accenture All Rights Reserved. 4


Architecture

2003 Accenture All Rights Reserved. 5


Architecture
Stored procedure compilation produces object code which is
interpreted by pl/sql engine.
Native compilation into byte-code is possible from oracle 9i
Stored Procedures are loaded in Library cache in shared pool of
SGA. This is controlled by shared_pool_size init.ora parameter
Pin the stored procedure in memory to improve performance.
Oracle provides API to do this
execute dbms_shared_pool.keep('DBMS_ALERT');
Pinning should be done after every start up
View v$db_object_cache provides list of all objects in shared pool
cache

2003 Accenture All Rights Reserved. 6


Benefits of PL/SQL
Improved performance
PL/SQL can be used to group SQL statements together within a single
block and to send the entire block to the server in a single call, thereby
reducing networking traffic

SQL
SQL
SQL
Application SQL Other DBMSs

SQL

SQL
IF...THEN
SQL Oracle with
Application PL/SQL
ELSE
SQL
END IF;
2003 Accenture All Rights Reserved. SQL 7
Benefits of PL/SQL

Group logically related statements within blocks

Nest sub-blocks inside larger blocks to build powerful programs

Break down a complex problem into a set of manageable,


well-defined, logical modules and implement the modules with
blocks

PL/SQL is portable. Can be invoked from other environments

You can program with procedural language control structures

2003 Accenture All Rights Reserved. 8


Benefits of PL/SQL
Error Handling

Improved data security and integrity

Improved performance allows you to :

Avoid reparsing for multiple users by exploiting the shared


SQL area

Avoid PL/SQL parsing at run time by parsing at compile time

Reduce the number of calls to the database and decrease


network traffic by bundling commands

2003 Accenture All Rights Reserved. 9


Invoking Stored program units
Scott LOG_EXECUTION
procedure
1 xxxxxxxxxxxxxx
vvvvvvvvvvvvvv
xxxxxxxxxxxxxx
2 vvvvvvvvvvvvvv
xxxxxxxxxxxxxx
vvvvvvvvvvvvvv
xxxxxxxxxxxxxx

xxxxxxxxxxxxxx
vvvvvvvvvvvvvv
3 vvvvvvvvvvvvvv
xxxxxxxxxxxxxx
xxxxxxxxxxxxxx vvvvvvvvvvvvvv
Oracle Oracle Oracle vvvvvvvvvvvvvv
xxxxxxxxxxxxxx
Portal Discoverer Forms vvvvvvvvvvvvvv
xxxxxxxxxxxxxx
Developer vvvvvvvvvvvvvv
xxxxxxxxxxxxxx
vvvvvvvvvvvvvv

4
Scott

2003 Accenture All Rights Reserved. 10


Block Structure
A PL/SQL block consists of
an optional declaration section
an execution section and
one or more optional exception handler sections

Declaration section declares PL/SQL variables, exceptions, and


cursors

Execution section contains PL/SQL code and SQL statements, control


structures (loops), conditional statements (IFEND IF) and can
contain nested blocks

Exception handler section contain code that is called when the


exception is raised, either as a predefined PL/SQL exception or as an
exception that you define

2003 Accenture All Rights Reserved. 11


Block Structure
[<Block header>]
DECLARE [Optional]
[declare]
<Constants>


BEGIN [Mandatory] <Variables>
<Cursors>
<User defined exceptions>


EXCEPTION [Optional] [begin]
<PL/SQL statements>
[exception]
END; [Mandatory] <Exception handling>
end;

2003 Accenture All Rights Reserved. 12


Types of PL/SQL

Anonymous block

Stored Procedure

Function

Package

Trigger

2003 Accenture All Rights Reserved. 13


Anonymous Block
An anonymous block is a PL/SQL program unit that has no name

An anonymous block
cannot take input arguments and return output values
cannot be called concurrently by multiple users
is not stored in the data dictionary

Anonymous blocks are usually used interactively from a tool, such


as SQL*Plus, or in a precompiler, OCI, or SQL*Module application

They are usually used to call stored procedures or to open cursor


variables

2003 Accenture All Rights Reserved. 14


Display output from Stored Procs
Package DBMS_OUTPUT enables you to print / display output from
PL/SQL blocks and subprograms
The procedure put_line outputs information to a buffer in the SGA. You
display the information by setting SERVEROUTPUT ON in SQL*Plus
SQL> SET SERVEROUTPUT ON
SQL> BEGIN
2 DBMS_OUTPUT.PUT_LINE(Hello World');
3 END;
4 /
Hello World
PL/SQL procedure successfully completed

2003 Accenture All Rights Reserved. 15


Examples

Example1:

SQL> set serveroutput on


SQL> BEGIN
2 dbms_output.put_line(Welcome to PL/SQL);
3 END;
4 /

2003 Accenture All Rights Reserved. 16


Examples
Example2:

DECLARE
Emp_number INTEGER := 7369;
Emp_name VARCHAR2(10);
BEGIN
SELECT Ename INTO Emp_name FROM Emp
WHERE Empno = emp_number;
DBMS_OUTPUT.PUT_LINE('Employee name is ' || Emp_name);
EXCEPTION WHEN NO_DATA_FOUND THEN
DBMS_OUTPUT.PUT_LINE('No such employee: ' ||
Emp_number);
END;
/

2003 Accenture All Rights Reserved. 17


Declaring Variables
Agenda

Basic PL/SQL Block and Its Sections

Significance of Variables in PL/SQL

Distinguishing Between PL/SQL and Non-PL/SQL Variables

Declaring Variables and Constants

Executing a PL/SQL Block

2003 Accenture All Rights Reserved. 19


PL/SQL Block and Its Sections

Anonymous/Named Block or
DECLARE (Optional) Stored Procedure or Function
Variables, Cursors
Variable Declaration Section
Exceptions etc...
BEGIN (Mandatory)

SQL Statements
Program Section
PL/SQL Statements

EXCEPTION (Optional)

Action to perform when Exception Handling Section


error occurs...

END; (Mandatory)
/

2003 Accenture All Rights Reserved. 20


Significance of Variables

Variables can be used for:


Temporary storage of data
Manipulation of stored values
Reusability
Ease of maintenance

This is facilitated by the way variables are handled in PL/SQL:


Variables are declared and initialized in the declaration section
Variables are assigned new values in the executable section
Values are passed to PL/SQL blocks through parameters
Output variables are used to view the results

2003 Accenture All Rights Reserved. 21


Distinguishing PL/SQL and
Non-PL/SQL Variables

PL/SQL variables
Scalar (ex: NUMBER, VARCHAR2 etc...)
Composite (ex: TABLE, VARRAY etc...)
Reference (ex: REF cursors etc...)
LOB (large objects) (ex: LOB, BLOB etc...)

Non-PL/SQL variables
Bind and host variables

2003 Accenture All Rights Reserved. 22


PL/SQL Datatypes

2003 Accenture All Rights Reserved. 23


Non PL/SQL Datatypes
Bind and host variables
PL/SQL doesnt have input or output capability of its own
iSQL*Plus host variables are used to pass run time values out
of the PL/SQL block back to the iSQL*Plus environment

Front End
Display

O/S
Bind Variable

Server

2003 Accenture All Rights Reserved. 24


Example of using BIND Variables

SQL> variable h_sal number


SQL> variable h_ename varchar2(50)

SQL> begin
2 select ename, sal
3 into :h_ename, :h_sal
4 from emp
5 where empno=7369;
6 end;
/

SQL> print h_ename h_sal

2003 Accenture All Rights Reserved. 25


Declaring Variables and
Constants
Basic Syntax
identifier [CONSTANT]* datatype [NOT NULL]*
[:= | DEFAULT expr]; * value must be assigned while declaring
Examples
v_hiredate DATE;
v_deptno NUMBER(2) NOT NULL := 10;
v_location VARCHAR2(13) := 'Atlanta';
v_mgr NUMBER(6) DEFAULT 100;

c_comm CONSTANT NUMBER := 1400;

The Variable name should not be more than 30 characters


Adopt a naming convention for PL/SQL identifiers:
for example, v_variablename
2003 Accenture All Rights Reserved. 26
Executing a PL/SQL Block
From SQL* Plus editor
Once finished writing the block, press /
Specify the location of the file which contains the PL/SQL block (i.e.
SQL>@C:/PL-SQL/filename.sql)

View Output
Use DBMS_OUTPUT.PUT_LINE() in the PL/SQL block
Type set serverout on; from the SQL prompt

View Error
Type show errors; form the SQL prompt

2003 Accenture All Rights Reserved. 27


Scope of Variable
Declare Scope of Variable C is limited to the
A number; block displayed in RED
Begin
declare Scope of Variable B is limited to the
B number; block displayed in GREEN
begin
declare Scope of Variable A is across block
C number; displayed in BLUE
begin
..Statements
end;
..Statements..
end;
..Statements..
end;
/

2003 Accenture All Rights Reserved. 28


Writing Control Structures
Agenda

Identifying the Uses and Types of Control Structures

Constructing Conditional Statements

Constructing and Identifying Different Loop Statements

Controlling Block Flow Using Nested Loops and Labels

2003 Accenture All Rights Reserved. 30


Identifying the Uses and Types
of Control Structures

TYPES of Control Structures

IF Statement (IF ... THEN [ELSIF ... THEN ELSE ...] END IF;)

CASE Statement

Simple Loop

While Loop

FOR Loop

2003 Accenture All Rights Reserved. 31


Constructing IF Statements
Conditions must evaluate
IF Conditional Statement... to either TRUE or
FALSE.
IF condition THEN Statements are executed
sequence_of_statements; only when the associated
condition evaluates to
[ELSIF condition THEN TRUE.
sequence_of_statements;] If the condition evaluates
[ELSE to NULL, those statements
corresponding to that
sequence_of_statements;] condition will not be
END IF; executed.
Can have as many
ELSIF sections as
required, but only one IF
and ELSE section.
2003 Accenture All Rights Reserved. 32
Constructing CASE
Statements
The test_variable can be
CASE Statement simply a variable or an
[<<label>>] expression which call a
function to get the value.
CASE test_variable
ELSE section is optional,
WHEN value1 THEN and if the expression does
sequence_of_statements; not match any value and if
there is no ELSE section
WHEN value2 THEN in the CASE statement, it
sequence_of_statements; will throw
CASE_NOT_FOUND
... error.
[ELSE A label after END CASE
sequence_of_statements;] is legal only if the CASE
statement itself is labeled,
END CASE [label]; and the two labels must
match.
2003 Accenture All Rights Reserved. 33
Example: IF Statement
Declare
V_sal emp.sal%type;
V_emp_name emp.ename%type;
Begin
Select ename, sal into v_emp_name, v_sal
from emp
where empno = 7369;
If v_sal > 5000 then
dbms_output.put_line(Salary is greater than 5000);
Else
dbms_output.put_line(Salary is less than 5000);
End if;
End;
/

2003 Accenture All Rights Reserved. 34


Constructing CASE
Statements
Searched CASE Statements

CASE
WHEN bool_expr1 THEN
sequence_of_statements;
WHEN bool_expr2 THEN
sequence_of_statements;
...
[ELSE
sequence_of_statements;]
END CASE;

2003 Accenture All Rights Reserved. 35


Constructing CASE
Statements
Example:
DECLARE
v_test1 NUMBER := 1;
v_test2 VARCHAR2(20) := ACN;
BEGIN
CASE
WHEN v_test1 = 1 THEN
dbms_output.put_line(Value in v_test1 is ||to_char(v_test1)
);
WHEN v_test2 = ACN THEN
dbms_output.put_line(Value in v_test2 is || v_test2 );
ELSE
null;
END CASE;
END;
/

2003 Accenture All Rights Reserved. 36


LOOP Statements

LOOP Statement In a normal loop statement


EXIT statement can come at
LOOP any point in the sequence of
statements; statements inside the loop
statement
EXIT [WHEN condition];
While loop can also contain
END LOOP; an EXIT statement
Number of iterations is not
WHILE LOOP Statement known in either of the LOOP
or WHILE LOOP statements
WHILE condition LOOP
Loops also can be labeled,
statements; which will be useful while
END LOOP; using nested loops

2003 Accenture All Rights Reserved. 37


Example: While Loop
Declare
A number := 0;
begin
While a < 10 LOOP
a := a + 1 ;
Dbms_output.put_line(to_char(a) );
END LOOP;
END;
/

2003 Accenture All Rights Reserved. 38


LOOP Statements
Counter is an implicitly declared
variable
Difference of l_bound and
FOR LOOP Statements u_bound specifies the number of
iterations that a FOR LOOP will
FOR counter IN [REVERSE] perform
l_bound..u_bound While entering FOR LOOP
LOOP counter will be assigned the value
of l_bound and incremented by 1
statements; for every iteration till it reaches the
END LOOP; value of u_bound
REVERSE key word is optional: If
reverse key word is used, counter
will be assigned the value of
u_bound and decremented by 1
for every iteration till it reaches the
value of l_bound.
2003 Accenture All Rights Reserved. 39
Example: FOR Loop
Declare
A number := 0;
begin
FOR i in 1..10 LOOP
a := a + i ;
Dbms_output.put_line(to_char(i) || || to_char(a) );
END LOOP;
END;
/

2003 Accenture All Rights Reserved. 40


Example 2: FOR Loop
Declare
A number := 0;
begin
FOR i in REVERSE 1..10 LOOP
a := a + i ;
Dbms_output.put_line(to_char(i) || || to_char(a) );
END LOOP;
END;
/

2003 Accenture All Rights Reserved. 41


Interacting with the Oracle Server
Agenda

Writing a Successful SELECT Statement in PL/SQL

Declaring the Data type and Size of a PL/SQL Variable


Dynamically

Writing Data Manipulation Language (DML) Statements in PL/SQL

Controlling Transactions in PL/SQL

Determining the outcome of SQL DML Statements

Writing Explicit Cursors

2003 Accenture All Rights Reserved. 43


Writing a Successful SELECT
Statement

Select creates a virtual table, which exists only for the duration of
execution of the SQL statement

Select statement in PL/SQL uses into clause

The SELECT INTO statement retrieves data from one or more


database tables, then assigns the selected values to variables or
fields

The following SELECT statement returns an employees name, job


title, and salary from the emp database table:

2003 Accenture All Rights Reserved. 44


Writing a Successful
SELECT Statement in PL/SQL
SELECT ename, job, sal INTO
my_ename,my_job,my_sal FROM emp
WHERE empno = my_empno;

The select statement can be used with the BULK Collect clause.
This is used to retrieve multiple rows of data

When you use a SELECT INTO statement without the BULK


COLLECT clause, it should return only one row. If it returns more
than one row, PL/SQL raises the predefined exception
TOO_MANY_ROWS

2003 Accenture All Rights Reserved. 45


Declaring Data type and Size of
a PL/SQL Variable
Dynamically
Variables can be declared dynamically by using two types of
attributes:
%Rowtype
%Type

The %ROWTYPE attribute provides a record type that represents


a row in a database table

Fields in a record and corresponding columns in a row have the


same names and datatypes

The %ROWTYPE attribute can be used in variable declarations as


a datatype specifier

2003 Accenture All Rights Reserved. 46


Declaring Data type and Size
of a PL/SQL Variable
Dynamically

In the example below, %ROWTYPE is used to declare two


records. The first record stores a row selected from the emp table.
The second record stores a row fetched from the c1 cursor

1)DECLARE
emp_rec emp%ROWTYPE;
CURSOR c1 IS
SELECT deptno, dname, loc FROM dept;

2)dept_rec c1%ROWTYPE;

2003 Accenture All Rights Reserved. 47


Declaring Data type and Size
of a PL/SQL Variable
Dynamically

The %TYPE attribute provides the datatype of a field, record,


nested table, database column, or variable

In the following example, %TYPE provides the datatype of a


variable:
credit REAL(7,2);
debit credit%TYPE;

The %TYPE attribute is particularly useful when declaring


variables that refer to database columns Example:
my_dname scott.dept.dname%TYPE;

2003 Accenture All Rights Reserved. 48


Declaring the Data type and
Size of a PL/SQL Variable
Dynamically

Using %TYPE to declare my_dname has two advantages. First,


you need not know the exact datatype of dname. Second, if the
database definition of dname changes, the datatype of my_dname
changes accordingly at run time

2003 Accenture All Rights Reserved. 49


Data Manipulation Language
(DML) Statements in PL/SQL

The DML statements include:


INSERT
UPDATE
DELETE

Example of an Insert statement in pl/sql procedure:


CREATE PROCEDURE create_dept (
my_deptno NUMBER, my_dname VARCHAR2,
my_loc VARCHAR2) AS
BEGIN
INSERT INTO dept VALUES (my_deptno, my_dname, my_loc);
END;

2003 Accenture All Rights Reserved. 50


Data Manipulation Language
(DML) Statements in PL/SQL

Example 1 (UPDATE Statement in PL/SQL)

PROCEDURE raise_salary (emp_id Number, amount Number)


IS
BEGIN
UPDATE emp SET sal = sal + amount
WHERE empno = emp_id;
END raise_salary;

2003 Accenture All Rights Reserved. 51


Data Manipulation Language
(DML) Statements in PL/SQL

Example 2 (DELETE Statement in PL/SQL)

PROCEDURE fire_employee (emp_id INT) IS


BEGIN
DELETE FROM emp WHERE empno = emp_id;
END fire_employee;

2003 Accenture All Rights Reserved. 52


Controlling Transactions in
PL/SQL

A transaction is a series of SQL data manipulation statements that


does a logical unit of work

The transactions are controlled by using:

COMMIT
ROLLBACK
SAVEPOINT

The COMMIT statement ends the current transaction and makes


changes permanent. Until you commit the changes, other users
cannot access the changed data; they see the data as it was
before you made the changes

2003 Accenture All Rights Reserved. 53


Controlling Transactions in
PL/SQL

Example for commit:


Consider a simple transaction that transfers money from one bank
account to another. The transaction requires two updates because
it debits the first account, then credits the second. After crediting
the second account commit is issued, which makes the changes
permanent. Only then the other users can see the changes

The ROLLBACK statement ends the current transaction and


undoes any changes made during that transaction

2003 Accenture All Rights Reserved. 54


Controlling Transactions in
PL/SQL

The Rollback has two advantages:

- If you make a mistake like deleting the wrong row from a table, a
rollback restores the original data

- If you start a transaction that you cannot finish because an


exception is raised or a SQL statement fails, a rollback lets you
return to the starting point to take corrective action and perhaps
try again

2003 Accenture All Rights Reserved. 55


Controlling Transactions in
PL/SQL

Consider the example, in which you insert information about an


employee into three different database tables. All three tables
have a column that holds employee numbers and is constrained
by a unique index. If an INSERT statement tries to store a
duplicate employee number, the predefined Exception
DUP_VAL_ON_INDEX is raised. In that case, you want to undo all
changes, so you issue a rollback in the exception handler

SAVEPOINT names and marks the current point in the processing


of a transaction

2003 Accenture All Rights Reserved. 56


Controlling Transactions in
PL/SQL

Used with the ROLLBACK TO statement, savepoints let you undo


parts of a transaction instead of the whole transaction

Example for save point:

Mark a savepoint before doing an insert. If the INSERT statement


tries to store a duplicate value, the predefined exception
DUP_VAL_ON_INDEX is raised. In that case, you rollback to the
savepoint, undoing just the INSERT

2003 Accenture All Rights Reserved. 57


Cursors in PL/SQL
CURSOR
1. For every SQL statement execution certain area in memory is
allocated
2. PL/SQL allows you to name this area - Context Area/Cursor
3. Cursor represents a structure or result set in memory

CURSOR Variable
1. Writing a Cursor in the PL/SQL - Declaring Cursor Variable
2. Opening Cursor - Cursor Variable points to the Context
Area/Cursor

Types of cursors
1. Implicit Cursor
2. Explicit Cursor

2003 Accenture All Rights Reserved. 58


CURSOR Attributes
%NOTFOUND
It is a Boolean attribute, which evaluates to true, if the last fetch
failed i.e. when there are no rows left in the cursor to fetch

%FOUND
Boolean variable, which evaluates to true if the last fetch,
succeeded

%ROWCOUNT
Its a numeric attribute, which returns number of rows fetched by
the cursor so far

%ISOPEN
A Boolean variable, which evaluates to true if the cursor is opened
otherwise to false
2003 Accenture All Rights Reserved. 59
Distinguish between Implicit
and Explicit Cursor
Implicit Cursors
Any SQL or DML statements that are written in the PL/SQL
executable section is declared as an implicit cursor by PL/SQL
Engine
Cursor operations are automatically performed by Oracle.
We do not have any programmatic control on the Implicit
cursors
Only recently executed SQL or DML statements information
can be read from the cursors attributes
Explicit Cursors
Only SQL statements that are explicitly declared as cursors in
the declaration section of the PL/SQL block is treated as an
Explicit Cursor

2003 Accenture All Rights Reserved. 60


Implicit Cursor Attributes
Example1:
BEGIN
UPDATE emp SET ename=RAM;
IF (SQL%NOTFOUND) THEN
INSERT INTO EMP(...) VALUES (...);
END IF;
END;
Example2:
BEGIN
UPDATE emp SET ename=RAM;
IF (SQL%ROWCOUNT = 0) THEN
INSERT INTO EMP(...) VALUES (...);
END IF;
END;

2003 Accenture All Rights Reserved. 61


CURSOR Operations
DECLARE
CURSOR <cursor-name> IS <select statement>;

OPEN
OPEN <cursor-name>;

FETCH
FETCH <cursor-name> INTO <var1,var2,...>;

CLOSE
CLOSE <cursor-name>;

2003 Accenture All Rights Reserved. 62


Cursor Example (Simple
Loop...)
DECLARE
v_fname VARCHAR2(20);
CURSOR c_emp IS SELECT ename FROM emp;
BEGIN
OPEN c_emp;
LOOP
FETCH c_emp INTO v_fname;
EXIT WHEN c_emp%NOTFOUND;
DBMS_OUTPUT.PUT_LINE(Name: ||v_fname );
END LOOP;
CLOSE c_emp;
END;
/
2003 Accenture All Rights Reserved. 63
Cursor Example (Simple
Loop...)
DECLARE
v_fname VARCHAR2(20);
V_sal number;
CURSOR c_emp IS SELECT ename, sal FROM emp;
BEGIN
OPEN c_emp;
LOOP
FETCH c_emp INTO v_fname,v_sal;
EXIT WHEN c_emp%NOTFOUND;
DBMS_OUTPUT.PUT_LINE(Name: ||v_fname|| ||to_char(v_sal) );
END LOOP;
CLOSE c_emp;
END;
/2003 Accenture All Rights Reserved. 64
Cursor Example (Simple
Loop...)
DECLARE
v_emp emp%rowtype;
CURSOR c_emp IS SELECT * FROM emp;
BEGIN
OPEN c_emp;
LOOP
FETCH c_emp INTO v_emp;
EXIT WHEN c_emp%NOTFOUND;
DBMS_OUTPUT.PUT_LINE(Name: ||v_emp.ename|| ||
to_char(v_emp.sal) );
END LOOP;
CLOSE c_emp;
END;
/2003 Accenture All Rights Reserved. 65
Cursor Example
(WHILE Loop...)
DECLARE
v_name emp%ROWTYPE;
CURSOR c_emp IS SELECT * FROM emp;
BEGIN
OPEN c_emp;
WHILE c_emp%FOUND
LOOP
FETCH c_emp INTO v_name;
DBMS_OUTPUT.PUT_LINE(Name: ||v_name.ename);
END LOOP;
CLOSE c_emp;
END;
/

2003 Accenture All Rights Reserved. 66


Cursor FOR Loop
Cursor FOR loops have the advantage of providing the functionality of
a cursor fetch loop simply and cleanly, with a minimum syntax...

Declaring Cursor for FOR loop is same as the normal statement


Variables required to fetch the data from cursor need not be
declared
Type of the variable is automatically taken as cursor%ROWTYPE
Cursor Operations:
Just before FOR loop starts, OPEN operation is performed
At the beginning of every iteration, FETCH operation is
performed and the %FOUND attribute is checked to make sure
there are remaining rows in the active set
When the active set is completely fetched, the cursor is closed
as the loop ends by performing CLOSE operation

2003 Accenture All Rights Reserved. 67


Cursor Example (FOR Loop...)
DECLARE
CURSOR c_emp IS SELECT ename FROM emp;
BEGIN
-- OPEN cursor implicitly executed here
FOR v_name IN c_emp - FETCH cursor implicitly executed here
-- %FOUND Cursor checked for active records
LOOP
DBMS_OUTPUT.PUT_LINE(Name: || v_name.ename);
END LOOP;
-- CLOSE cursor implicitly executed here
END;
/

2003 Accenture All Rights Reserved. 68


Cursor Example (FOR Loop...)
DECLARE
CURSOR c_emp IS SELECT ename FROM emp;
BEGIN
-- OPEN cursor implicitly executed here
FOR v_name IN c_emp - FETCH cursor implicitly executed here
-- %FOUND Cursor checked for active records
LOOP
DBMS_OUTPUT.PUT_LINE(Name: || v_name.ename);
END LOOP;
-- CLOSE cursor implicitly executed here
END;
/

2003 Accenture All Rights Reserved. 69


Cursor Example (FOR Loop...)
BEGIN
FOR v_name IN (SELECT ename FROM emp)
LOOP
DBMS_OUTPUT.PUT_LINE(Name: ||
v_name.ename);
END LOOP;
END;
/

2003 Accenture All Rights Reserved. 70


Parameterized Cursors
A Parameterized Cursor takes arguments, similar to a PL/SQL
Procedure or Function
We do not have to hardcode any value in the WHERE clause,
instead we can pass the variable as a parameter to the cursor
If we are using the same SQL statement with different WHERE
clauses, instead of writing cursors for each of the different criteria,
we can generalize the cursor by declaring a parameterized cursor
The scope of the cursor parameter is confined to that cursor
Only the syntax of Declaring and Opening the cursor differs, with
the normal cursor operation syntax
Observe that cursor can have IN parameters only unlike in
procedures and functions we have IN, OUT and IN OUT as the
mode of parameter

2003 Accenture All Rights Reserved. 71


Parameterized Cursor Example
DECLARE
v_deptname varchar2(10) := 'SALES';
CURSOR c_emp (p_deptno emp.deptno%TYPE) IS SELECT ename FROM emp WHERE deptno =
p_deptno;
BEGIN

IF (v_deptname = 'SALES') THEN

for t1 in c_emp(10)
loop
dbms_output.put_line(t1.ename);
end loop;

ELSE

for t1 in c_emp(20)
loop
dbms_output.put_line(t1.ename);
end loop;

END IF;
END;
/

2003 Accenture All Rights Reserved. 72


FOR UPDATE Cursors
SELECT...FOR UPDATE cursor will be used to lock some set of
records for modifying or updating

SELECT...FOR UPDATE statement obtains exclusive row-level


locks on all the rows identified by the SELECT statement

After a ROLLBACK or COMMIT, we cannot further perform a


FETCH against this type of cursor, as ROLLBACK or COMMIT
closes or invalidates the cursor

We can use FOR UPDATE clause in a SELECT against multiple


statements

2003 Accenture All Rights Reserved. 73


FOR UPDATE Cursor
Syntax and Example
Syntax:
CURSOR c_name IS SELECT...FROM <table1>...FOR
UPDATE [OF <column_references>] [NOWAIT/WAIT n];

UPDATE table1 SET ... WHERE CURRENT OF c_name;

The OF list of the FOR UPDATE clause does not restrict you to
changing only those columns listed

NOWAIT/WAIT clause tells oracle not to wait/wait for n seconds


before it acquires a lock. If this clause is not specified then oracle
waits till the lock is released on the table and rows by other user

2003 Accenture All Rights Reserved. 74


FOR UPDATE Cursor
Syntax and Example
Example:

DECLARE
CURSOR c_emp IS SELECT ename FROM emp FOR UPDATE
OF sal NOWAIT;
BEGIN
FOR v_emp IN c_emp LOOP
UPDATE emp SET sal = (sal+comm)*1.2
WHERE CURRENT OF c_emp;
END LOOP;
END;

2003 Accenture All Rights Reserved. 75


Reference Cursors
(REF CURSOR)
All the explicit cursors that we have seen till now are static cursors

Static cursors are like constants because they can be associated


with one runtime query

A cursor variable, can be associated with different queries at


runtime REF Cursor

Advantages of REF cursor is that we can pass a cursor variable as


an argument to a procedure of function

2003 Accenture All Rights Reserved. 76


Cursor Operations on
REF Cursor
Declaring REF Cursor
TYPE c_name IS REF CURSOR [RETURN <return type>]
A cursor with RETURN type is called strong cursor
A cursor without RETURN type is called week cursor
OPENING REF Cursor
OPEN c_name FOR <select statement>;
Fetching
FETCH c_name INTO <record name>;
FETCH c_name INOT <var1,var2,...>;
Closing
CLOSE c_name;
Note: Syntax for FETCH and CLOSE operations are same as that for
static cursors...

2003 Accenture All Rights Reserved. 77


REF CURSOR: Passing as a
Parameter

CREATE OR REPLACE PACKAGE ref_cursor_example AS


TYPE c_emptype IS REF CURSOR;
PROCEDURE sp_cur_example(pc_emp OUT c_emptype);
END ref_cursor_example;

PROCEDURE sp_cur_example
(pc_emp OUT c_emptype) AS
BEGIN
OPEN c_emp FOR select * FROM emp;
END;

2003 Accenture All Rights Reserved. 78


REF Cursor: Passing as a
Parameter
SQL>DECLARE
c_emptable c_emptype;
v_emprec emp%ROWTYPE;
BEGIN
sp_cur_example(c_emptable);
LOOP
FETCH c_emptable INTO v_emprec;
DBMS_OUTPUT.PUT_LINE(v_emprec.first_name);
END LOOP;
END;
/

2003 Accenture All Rights Reserved. 79


Composite Datatypes
Agenda

PL/SQL Table

PL/SQL Record

2003 Accenture All Rights Reserved. 81


PL/SQL Table
A PL/SQL table is a one-dimensional, unbounded, sparse
collection of homogeneous elements, indexed by integers

It is analogous to an array and a SQL table

A PL/SQL table is one type of collection structure

2003 Accenture All Rights Reserved. 82


PL/SQL Table Structure
Unique Identifier Field1 (data type)

Example:

Binary_Integer dept_name varchar2(14)


1 Accounting
2 Research
3 Sales

2003 Accenture All Rights Reserved. 83


PL/SQL Table Characteristics
One-dimensional
A PL/SQL table can have only one column

Unbounded or Unconstrained
There is no predefined limit to the number of rows in a PL/SQL
table. The PL/SQL table grows dynamically as you add more rows
to the table

No rows for PL/SQL tables are allocated for this structure when it
is defined

2003 Accenture All Rights Reserved. 84


PL/SQL Table Characteristics
Sparse
In a PL/SQL table, a row exists in the table only when a value is
assigned to that row. Rows do not have to be defined sequentially.
Can assign a value to any row in the table. Row 15 could have a
value of `Fox' and row 15446 a value of `Red', with no other rows
defined in between

Homogeneous elements
As a PL/SQL table can have only a single column, all rows in a
PL/SQL table contain values of the same datatype

Indexed by integers
PL/SQL tables currently support a single indexing mode: by
BINARY_INTEGER. This number acts as the "primary key" of the
PL/SQL table. The range of a BINARY_INTEGER is from -231-1
to 231-1
2003 Accenture All Rights Reserved. 85
PL/SQL Table Characteristics
The PL/SQL table structure is not a part of the SQL language

Standards restrictions with PL/SQL tables:

There is no concept of transaction integrity with PL/SQL tables


You cannot commit information to a PL/SQL table or roll back
changes from the table
You cannot SELECT from PL/SQL tables. There is no set
based processing to retrieve data from a PL/SQL table. This is
a programmatic construct in a programmatic language. Can
use PL/SQL loops to move through the contents of a PL/SQL
table, one row at a time
Cannot issue DML statements (INSERTs, UPDATEs, and
DELETEs) against PL/SQL tables

2003 Accenture All Rights Reserved. 86


Declaring a PL/SQL Table
A PL/SQL table is declared in two stages:

Define a particular PL/SQL table structure (made up of strings,


dates, etc.) using the table TYPE statement. The result of this
statement is a datatype you can use in declaration statements

TYPE <table_type_name> IS TABLE OF <datatype>


[ NOT NULL ] INDEX BY BINARY_INTEGER;

Declare the actual table based on that table type. The declaration
of a PL/SQL table is a specific instance of a generic datatype

<table_name> <table_type>;

2003 Accenture All Rights Reserved. 87


Referencing and Modifying
PL/SQL Table Rows

Refer to a particular row in a PL/SQL table by specifying the name of


the table and the primary key value for that row

Syntax:
<table_name> ( <primary_key_value> )

2003 Accenture All Rights Reserved. 88


Populate Rows of PL/SQL Table
Rows can be populated in PL/SQL Table in 3 methods

1) Direct assignment

2) Iterative assignment

3) Aggregate assignment

2003 Accenture All Rights Reserved. 89


Direct assignment
DECLARE
TYPE tab_type IS TABLE OF NUMBER INDEX BY binary_integer;
iter_tab tab_type;
BEGIN
iter_tab(1) := 100;
iter_tab(2) := 200;
iter_tab(3) := 300;
iter_tab(4) := 400;
FOR j IN 1..iter_tab.count
LOOP
DBMS_OUTPUT.PUT_LINE(to_char(iter_tab(j)));
END LOOP;
END;
/

2003 Accenture All Rights Reserved. 90


Iterative assignment
DECLARE
TYPE tab_type IS TABLE OF NUMBER INDEX BY binary_integer;
iter_tab tab_type;
BEGIN
FOR i IN 1..10
LOOP
iter_tab(i) := i+10;
END LOOP;
FOR j IN 1..10
LOOP
DBMS_OUTPUT.PUT_LINE(to_char(iter_tab(j)));
END LOOP;
END;
/

2003 Accenture All Rights Reserved. 91


Aggregate assignment
DECLARE
TYPE name_table IS TABLE OF VARCHAR2(100) INDEX BY
BINARY_INTEGER;
old_names name_table;
new_names name_table;
BEGIN
/* Assign values to old_names table */
old_names(1) := 'Smith';
old_names(2) := 'Harrison';

/* Assign values to new_names table */


new_names(111) := 'Hanrahan';
new_names(342) := 'Blimey';

2003 Accenture All Rights Reserved. 92


Aggregate assignment
/* Transfer values from new to old */
old_names := new_names;

/* This assignment will raise NO_DATA_FOUND */


DBMS_OUTPUT.PUT_LINE (old_names (1));
END;
/

2003 Accenture All Rights Reserved. 93


Delete data from PL/SQL
Table
Set a single row to NULL with the following kind of assignment:
iter_tab (2) := NULL;

To empty a PL/SQL table of all rows perform an aggregate


assignment with a table that is empty

Cannot perform a SQL DELETE statement on a PL/SQL table


because it is not stored in the database

Cannot DROP a PL/SQL table

2003 Accenture All Rights Reserved. 94


Delete data from PL/SQL
Table
Example
DECLARE
TYPE tab_type IS TABLE OF NUMBER INDEX BY binary_integer;
iter_tab tab_type;
null_tab tab_type;
BEGIN
FOR i IN 1..10
LOOP
iter_tab(i) := i+10;
END LOOP;

FOR j IN 1..10
LOOP
DBMS_OUTPUT.PUT_LINE(TO_CHAR(iter_tab(j)));
END LOOP;
2003 Accenture All Rights Reserved. 95
Delete data from PL/SQL
Table

iter_tab := null_tab;

DBMS_OUTPUT.PUT_LINE('Printing after setting to null');

FOR j IN 1..10
LOOP
DBMS_OUTPUT.PUT_LINE(to_char(iter_tab(j)));
END LOOP;

DBMS_OUTPUT.PUT_LINE('After Print');
END;
/

2003 Accenture All Rights Reserved. 96


PL/SQL Table Built-In
Operator Description
COUNT Returns the number of elements currently contained in the PL/SQL
table
DELETE Deletes one or more elements from the PL/SQL table
EXISTS Returns FALSE if a reference to an element at the specified index
would raise the NO_DATA_FOUND exception
FIRST Returns the smallest index of the PL/SQL table for which an element is
defined
LAST Returns the greatest index of the PL/SQL table for which an element is
defined
NEXT Returns the smallest index of the PL/SQL table containing an element
which is greater than the specified index
PRIOR Returns the greatest index of the PL/SQL table containing an element
which is less than the specified index
2003 Accenture All Rights Reserved. 97
PL/SQL Record
PL/SQL record is a composite data structure similar to a single-
row of a database table

PL/SQL record as a whole does not have value of its own; instead,
each individual component or field has a value

PL/SQL record gives you a way to store and access individual


component values as a group

2003 Accenture All Rights Reserved. 98


PL/SQL Record Structure

Field1 (data type) Field2 (data type) Field3 (data type)

Example:

Field1 (data type) Field2 (data type) Field3 (data type)


dept_id number(2) dept_name
varchar2(14) dept_loc varchar2(13)
10 ACCOUNTING NEW YOR

2003 Accenture All Rights Reserved. 99


PL/SQL Record Types
Record Type Description Fields in Record
Table-based A record based on a Each field corresponds to -- and has
table's column the same name as -- a column in a
structure table.
Cursor- A record based on Each field corresponds to a column
based the cursor's SELECT or expression in the cursor SELECT
statement. statement
Programmer- A record whose Each field is defined explicitly (its
defined structure you, the name and datatype) in the TYPE
programmer, get to statement for that record; a field in a
define with a programmer-defined record can
declaration even be another record.
statement.

2003 Accenture All Rights Reserved. 100


Benefits of Using PL/SQL
Records
Data abstraction
Instead of working with individual attributes of an entity or
object, PL/SQL record helps manipulate that entity as a "thing
in itself"
Aggregate operations
Helps perform operations which apply to all the columns of a
record
Leaner, cleaner code
Helps write less code and more understandable code

2003 Accenture All Rights Reserved. 101


Table based Record
A table-based record, or table record, is a record whose structure (set of
columns) is drawn from the structure (list of columns) of a table. Each
field in the record corresponds to and has the same name as a column in
the table
DECLARE
dept_rec dept%ROWTYPE;
BEGIN
SELECT * INTO dept_rec FROM dept WHERE deptno= 10;
DBMS_OUTPUT.PUT_LINE('Dept name is : '||dept_rec.dname);
DBMS_OUTPUT.PUT_LINE('Location is : '||dept_Rec.loc);
END;
/

2003 Accenture All Rights Reserved. 102


Cursor Based Records
A cursor-based record, or cursor record, is a record whose structure is
drawn from the SELECT list of a cursor. Each field in the record
corresponds to and has the same name as the column or aliased
expression in the cursor's query
DECLARE
CURSOR dept_cursor is SELECT * FROM dept;
dept_rec dept_cursor%ROWTYPE;
BEGIN
OPEN dept_cursor;
LOOP
FETCH dept_cursor INTO dept_Rec;
EXIT WHEN dept_cursor%NOTFOUND;
DBMS_OUTPUT.PUT_LINE('Dept name is : '||dept_rec.dname);
END LOOP;
CLOSE dept_cursor;
END;
2003 Accenture All Rights Reserved. 103
Programmer-Defined Records
PL/SQL record which is a sub-set of table columns or from multiple tables
or views
DECLARE
TYPE emp_type IS RECORD (r_ename VARCHAR2(10), r_dname
VARCHAR2(10));
emp_rec emp_type;
BEGIN
SELECT ename,dname INTO emp_rec.r_ename,
emp_rec.r_dname FROM dept,emp WHERE
dept.deptno=emp.deptno and emp.empno= 7369;
DBMS_OUTPUT.PUT_LINE('Dept name is : '||emp_rec.r_dname);
DBMS_OUTPUT.PUT_LINE('Emp name is : '||emp_rec.r_ename);
END;
/

2003 Accenture All Rights Reserved. 104


Exception Handling
Agenda
PL/SQL Error Handling

Exception Handler Mechanism

User Defined Exception

PRAGMA Exception

2003 Accenture All Rights Reserved. 106


PL/SQL Error Handling
In PL/SQL, errors of any kind (situations that should not occur ) are
treated as Exceptions in your program

An exception can be one of the following:


An error generated by the system (such as "out of memory" or
"duplicate value in index")
An error caused by a user action
A warning issued by the application to the user

PL/SQL traps and responds to errors using an architecture of


exception handlers

2003 Accenture All Rights Reserved. 107


Exception Handler Mechanism
The exception-handler mechanism allows you to clearly separate
your error processing code from your executable statements

It provides an event-driven model, as opposed to a linear code


model, for processing errors

No matter how a particular exception is raised, it is handled by the


same exception handler in the exception section

The processing in the current PL/SQL block's execution section


halts and control is transferred to the separate exception section of
your program, if one exists, to handle the exception

You cannot return to that block after you finish handling the
exception. Instead, control is passed to the enclosing block, if any

2003 Accenture All Rights Reserved. 108


Advantages of Exception
Model
Event-driven handling of errors
You do not have to check repeatedly for a condition in your
code, but instead can insert an exception for that condition
once in the exception section and be certain that it will be
handled throughout that block
Clean separation of error-processing code
whenever an exception is raised, program control transfers
completely out of the normal execution sequence and into the
exception section. Programmer can consolidate all of this logic
into a single, separate section
Improved reliability of error handling
errors will not go undetected with the PL/SQL error-handling
model. Even if there is no explicit handler for that error, normal
code execution will still stop

2003 Accenture All Rights Reserved. 109


Exception Types
There are Two types of exceptions
System Defined
Raised automatically by the system when error occurs
User Defined
Raised explicitly in a sequence of statements using raise
<exception name>
Format
when <exception name> then <sequence of statements>;

2003 Accenture All Rights Reserved. 110


Exception Handling
Trap the exception Propagate the exception

DECLARE DECLARE

BEGIN BEGIN
Exception Exception
is raised is raised
EXCEPTION

Exception Exception
END; END;
is trapped is not
trapped
Exception
propagates to
calling environment
2003 Accenture All Rights Reserved. 111
Common Exceptions
System Exceptions the most common errors

Exception Name Number Remarks


CURSOR_ALREADY_OPEN ORA-06511 Try to open a cursor which is
already exist
INVALID_CURSOR ORA-01001 Invalid Cursor operation like
fetching from a closed cursor
NO_DATA_FOUND ORA-01403 Select statement returns no
data
TOO_MANY_ROWS ORA-01422 Expected one row but
returned more than one
ZERO_DIVIDE ORA-01476 Try to divide a number by 0.

2003 Accenture All Rights Reserved. 112


Generic Exception
OTHERS EXCEPTION HANDLER
Can be used as a generic
exception handler
Example Note:
DECLARE SQLCODE - Returns the
a number; number of the Oracle error
BEGIN for internal exceptions
SELECT 1 INTO a FROM emp SQLERRM - Returns the
WHERE empno='99'; message associated with
the error number
EXCEPTION WHEN OTHERS THEN
DBMS_OUTPUT.PUT_LINE(Error
||SQLCODE||' - '||SQLERRM);
END;
/
2003 Accenture All Rights Reserved. 113
PL/SQL Exception
Propagation

2003 Accenture All Rights Reserved. 114


PL/SQL Exception
Propagation

2003 Accenture All Rights Reserved. 115


PL/SQL Exception
Propagation

2003 Accenture All Rights Reserved. 116


User Defined Exceptions
PL/SQL lets you define exceptions of your own

User-defined exceptions must be declared and must be raised


explicitly by RAISE statements

The procedure RAISE_APPLICATION_ERROR lets you issue user-


defined ORA error messages from stored subprograms. By using this
built-in, you can report errors to your application and avoid returning
unhandled exceptions

2003 Accenture All Rights Reserved. 117


User Defined Exceptions
Syntax :

Raise_application_error(error_number, message[, {TRUE | FALSE}]);

WHERE
error_number is a negative integer in the range
20000 .. -20999
message is a character string up to 2048 bytes long
If TRUE, the error is placed on the stack of previous errors
If FALSE (the default), the error replaces all previous errors

2003 Accenture All Rights Reserved. 118


User Defined Exceptions
RAISE_APPLICATION_ERROR is part of package
DBMS_STANDARD, and as with package STANDARD, there is
no need to qualify references to it

An application can call raise_application_error only from an


executing stored subprogram (or method)

When called, raise_application_error ends the subprogram and


returns a user-defined error number and message to the
application

The error number and message can be trapped like any Oracle
error

2003 Accenture All Rights Reserved. 119


User Defined Exceptions
DECLARE
emp_name varchar2(10);
emp_number integer;
empno_out_of_range EXCEPTION;
BEGIN
emp_number := 10001;
IF emp_number > 9999 THEN
raise empno_out_of_range;
ELSE
SELECT ename INTO emp_name FROM emp WHERE
empno=emp_number;
END IF;
EXCEPTION
WHEN empno_out_of_range THEN
DBMS_OUTPUT.PUT_LINE (Emp No' || to_char(emp_number) ||' is out of
range.');
END;
2003 Accenture All Rights Reserved. 120
PRAGMA Exception
Apart from predefined exception, we can extend the list of exceptions
associated with an Oracle error within our PL/SQL code with the use of
PRAGMA EXCEPTION_INIT keyword

EXCEPTION PRAGMA is used to associate a named exception with a


particular Oracle error

This enable us to trap the error specifically, rather than via an


OTHERS handle

Only one user defined exception can be associated with one Oracle
error with each occurrence of PRAGMA EXCEPTION_INIT

This statement is a compiler directive that allows the developer to


declare the Oracle-numbered error to be associated with a named
exception in the block
2003 Accenture All Rights Reserved. 121
PRAGMA Exception
Example

declare
empname VARCHAR2(12);
no_record EXCEPTION;
PRAGMA EXCEPTION_INIT(no_record, 100);
BEGIN
select ename into empname from emp where empno=&9999;
dbms_output.put_line('Name :'||empname);
EXCEPTION
when no_record then
dbms_output.put_line('Error code is ' || SQLCODE);
dbms_output.put_line('Error message is '||SQLERRM);
dbms_output.put_line('No Record found');
END;
/
2003 Accenture All Rights Reserved. 122
PRAGMA Exception
Example 2
Trap for Oracle server error number 2292, an integrity constraint violation
DECLARE
p_deptno number := &deptno;
e_emps_remaining EXCEPTION;
PRAGMA EXCEPTION_INIT (e_emps_remaining, -2292);
BEGIN
DELETE FROM dept WHERE deptno = p_deptno;
IF SQL%NOTFOUND THEN
DBMS_OUTPUT.PUT_LINE ('No such dept '||to_char(p_deptno));
END IF;
EXCEPTION
WHEN e_emps_remaining THEN
DBMS_OUTPUT.PUT_LINE ('Cannot remove dept ' || TO_CHAR(p_deptno)
|| '. Employees exist. ');
END;
2003 Accenture All Rights Reserved. 123
PL/SQL Subprograms
Agenda
Subprogram Structure

Stored Procedures

Procedure Parameter Modes

Functions

Overloading

2003 Accenture All Rights Reserved. 125


Sub Program Structure
Declare
<Constants> <Variables> <Cursors>
Begin
<PL/SQL statements>
Begin
<PL/SQL statements>
Exception
<Exception handling>
End;
EXCEPTION
<Exception handling>
END;
/
2003 Accenture All Rights Reserved. 126
Stored Program Unit
A Stored Procedure, Function, or Package is a PL/SQL program unit
that:

Has a name
Can take input parameters, and can return output values
Is stored in the data dictionary
Can be called by many concurrent users
Synonyms can be created on stored program units
Data Access and execute privileges can be provided on stored
program units

2003 Accenture All Rights Reserved. 127


Stored procedure
A named PL/SQL block that performs one or more actions and is
called as an executable PL/SQL statement

A Program can pass information into and out of a procedure through


its parameter list

A stored procedure is defined by the keywords CREATE


PROCEDURE followed by the procedure name and its parameters

There can be any number of parameters, each followed by a mode


and a type. The possible modes are IN (read-only), OUT (write-only),
and INOUT (read and write)

2003 Accenture All Rights Reserved. 128


Stored Procedure
Syntax
CREATE [or REPLACE] PROCEDURE <procedure name>
[(<list of parameters>)] IS <declarations> IN | OUT | INOUT
Parameter
BEGIN
<sequence of statements> <parameter name> [IN |
OUT | IN OUT] <data type>
[EXCEPTION
[{ := | DEFAULT}
<exception handling routines>] <expression>]
END [<procedure name>];

2003 Accenture All Rights Reserved. 129


Procedure Parameter Modes

Procedure
IN parameter
Calling
environment OUT parameter
IN OUT parameter

procedure

BEGIN

EXCEPTION

END;

2003 Accenture All Rights Reserved. 130


Parameter Mode IN
IN - The IN parameter allows you to pass values in to the module,
but will not pass anything out of the module and back to the calling
PL/SQL block

IN parameters function like constants. Just like constants, the


value of the formal IN parameter cannot be changed within the
program. You cannot assign values to the IN parameter or in any
other way modify its value

IN is the default mode for parameters

IN parameters can be given default values in the program header

2003 Accenture All Rights Reserved. 131


Parameter Mode - IN
Example
Create or Replace Procedure MyProc2 (I_empno IN number) is
Emp_name VARCHAR2(10);
Begin
SELECT Ename INTO Emp_name FROM Emp
WHERE Empno = i_empno;
Dbms_output.put_line('Employee name is ' || Emp_name);
Exception WHEN NO_DATA_FOUND THEN
Dbms_output.put_line('No such employee: ' || i_empno);
End;
/

2003 Accenture All Rights Reserved. 132


Parameter Mode OUT
OUT - An OUT parameter is the opposite of the IN parameter. OUT
parameter is used to pass a value back from the program to the
calling PL/SQL block

OUT parameter is like the return value for a function, but it appears in
the parameter list and you can have as many OUT parameters as you
like. Inside the program OUT parameter acts like a variable that has
not been initialized

OUT parameter has no value at all until the program terminates


successfully. During the execution of the program, any assignments
to an OUT parameter are actually made to an internal copy of the
OUT parameter. When the program terminates successfully and
returns control to the calling block, the value in that local copy is then
transferred to the actual OUT parameter. That value is then available
in the calling PL/SQL block

2003 Accenture All Rights Reserved. 133


Parameter Mode OUT

Example

CREATE or REPLACE PROCEDURE MyProc3 (I_empno IN number,


O_ename OUT Varchar2) is
Emp_name VARCHAR2(10);
BEGIN
SELECT Ename INTO O_ename FROM Emp WHERE Empno =
i_empno;
EXCEPTION
WHEN NO_DATA_FOUND THEN
DBMS_OUTPUT.PUT_LINE('No such employee: ' || i_empno);
END;
/

2003 Accenture All Rights Reserved. 134


Executing the Stored
Procedure
DECLARE
v_ename varchar2(10);
BEGIN
Myproc3('7369',v_ename);
DBMS_OUTPUT.PUT_LINE('Emp name is '||v_ename);
END;

2003 Accenture All Rights Reserved. 135


Parameter Mode IN OUT
IN OUT - With an IN OUT parameter, you can pass values into the
program and return a value back to the calling program (either the
original, unchanged value or a new value set within the program)

IN OUT parameter shares two restrictions with the OUT


parameter:

- An IN OUT parameter cannot have a default value

- An IN OUT actual parameter or argument must be a


variable. It cannot be a constant, literal, or expression, since
these formats do not provide a receptacle in which PL/SQL
can place the outgoing value

2003 Accenture All Rights Reserved. 136


Discovering Errors
PL/SQL does not always tell you about compilation errors. Instead, it
gives you a cryptic message such as "procedure created with
compilation errors"

To show the compilation error use the command


SQL> show errors procedure <procedure_name>;

Alternatively, you can type, SHO ERR (short for SHOW ERRORS) to
see the most recent compilation error

2003 Accenture All Rights Reserved. 137


Function
A named PL/SQL block that returns a single value and is used just
like a PL/SQL expression

A program can pass information into a function through its parameter


list

Unlike a procedure, which is a standalone executable statement, a


call to a function can only be part of an executable statement

Because a function returns a value, it has a datatype

A function can be used in place of an expression in a PL/SQL


statement having the same datatype as the function

2003 Accenture All Rights Reserved. 138


Function

CREATE or <REPLACE> FUNCTION <func_name>(<param_list>)


RETURN <return_type> IS
BEGIN
<sequence of statements>
[EXCEPTION
<exception handling routines>]
END [<function name>];

2003 Accenture All Rights Reserved. 139


Function
Example

CREATE or REPLACE FUNCTION total_sal (p_empno IN number)


RETURN NUMBER is
n_total NUMBER;
BEGIN
SELECT nvl(sal,0)+nvl(comm,0) INTO n_total FROM emp
WHERE empno = p_empno;
RETURN(n_total);
EXCEPTION WHEN OTHERS THEN
DBMS_OUTPUT.PUT_LINE('Error occurred for emp : '||
to_char(p_empno));
RETURN(0);
END;
/
2003 Accenture All Rights Reserved. 140
Executing the Function
DECLARE
a number;
BEGIN
a := count_emp();
END;
/
Functions can be called from SQL statements and DML Statements

Example:
SELECT empno, ename, total_sal(empno) FROM emp WHERE empno
=7369;

UPDATE employee SET sal = total_sal(7369) WHERE empno = 7369;

INSERT INTO employee(empno, salary) VALUES(7369, total_sal(7369));


2003 Accenture All Rights Reserved. 141
Overloading
Two or more Procedures/Functions can have the same name with
different parameter lists

The parameter list of overloaded programs must differ by more than


parameter mode
Even if a parameter in one version is IN and that same parameter
is IN OUT in another version, PL/SQL cannot tell the difference at
the point in which the program is called

Overloaded functions must differ by more than their return type (the
datatype specified in the RETURN clause of the function)

All of the overloaded programs must be defined within the same


PL/SQL scope or block (anonymous block, module, or package)

2003 Accenture All Rights Reserved. 142


Data dictionary tables
Stored program units are available in 2 data dictionary tables

USER_OBJECTS

USER_SOURCE

SQL> select object_name, object_type, status from


user_objects where object_name=MYPROC;

SQL> select text from user_source where


name='MYPROC' order by line;

2003 Accenture All Rights Reserved. 143


Dropping Function/Procedure
Syntax
To Drop a Stored Procedure
DROP <Procedure> <Procedure_Name>;

To Drop a Function
DROP <Function> <Function_Name>;

Example
DROP FUNCTION total_sal;
/
DROP PROCEDURE MyProc;
/
2003 Accenture All Rights Reserved. 144
Triggers
Agenda
Definition and Advantages

Types of Triggers

INSTEAD OF Triggers

Manipulating Triggers

2003 Accenture All Rights Reserved. 146


Definition and Advantages
Triggers are a special PL/SQL construct similar to procedures

Trigger is executed implicitly whenever the triggering event happens

The trigger can be either row-level or statement-level, where the


former fires once for each row affected by the triggering statement and
the latter fires once for the whole statement

Triggers may be used to


supplement declarative referential integrity
enforce complex business rules
audit change to data
monitor database related actions
2003 Accenture All Rights Reserved. 147
Types of Triggers
Oracle supports Event Triggers in addition to the SQL Statement
and Row triggers
Oracle statement and row triggers are based on three types of
SQL statements: INSERT, UPDATE, and DELETE
The trigger timing may be either BEFORE" or AFTER
Statement-level triggers fire only once per SQL statement,
regardless of how many rows were processed
Row-level triggers fire once for each row that is affected by the
SQL statement
In addition to these, Oracle supports INSTEAD OF" triggers that
are valid only on views

2003 Accenture All Rights Reserved. 148


Row Level Trigger
Syntax:

2003 Accenture All Rights Reserved. 149


Row Level Trigger
Using OLD and NEW Qualifiers

Within a ROW trigger, reference the value of a column before and after
the data change by prefixing it with the OLD and NEW qualifier

The OLD and NEW qualifiers are available only in ROW triggers

Prefix these qualifiers with a colon (:) in every SQL and PL/SQL
statement

2003 Accenture All Rights Reserved. 150


Row Level Trigger
Example

CREATE OR REPLACE TRIGGER Print_salary_changes


AFTER UPDATE ON Emp FOR EACH ROW WHEN (new.Empno > 0)
DECLARE
sal_diff number;
BEGIN
sal_diff := :new.sal - :old.sal;
dbms_output.put_line('Old salary: ' || :old.sal);
dbms_output.put_line(' New salary: ' || :new.sal);
dbms_output.put_line(' Difference ' || sal_diff);
END;

2003 Accenture All Rights Reserved. 151


INSTEAD OF Trigger
Application
INSERT INTO my_view
. . .;

INSERT
TABLE1
INSTEAD OF
Trigger

UPDATE
MY_VIEW TABLE2

2003 Accenture All Rights Reserved. 152


Example: INSTEAD OF trigger
create view Myemp as select empno, deptno, ename from emp
/
create or replace trigger MyEmp_update_view
instead of
update on myemp
for each row
begin
update emp set ename = :new.ename
where empno = :new.empno;
end;
/
Update myemp set ename = Accenture
/
Select empno, ename from emp
/

2003 Accenture All Rights Reserved. 153


System Event Triggers
Syntax

CREATE [OR REPLACE] TRIGGER trigger_name


timing
[database_event1 [OR database_event2 OR ...]]
ON {DATABASE|SCHEMA}
trigger_body

Triggers are also used to monitor log on and log off


If you specify ON SCHEMA, the trigger fires for the specific user
If you specify ON DATABASE, the trigger fires for all users

2003 Accenture All Rights Reserved. 154


System Event Triggers
Example
CONNECT SYSTEM/password
GRANT ADMINISTER DATABASE TRIGGER TO scott;
CONNECT SCOTT/TIGER
CREATE TABLE AUDITING(USERNAME
VARCHAR2(12),LOGINDATE DATE);
CREATE OR REPLACE TRIGGER logontrig
AFTER LOGON ON DATABASE
BEGIN
INSERT INTO AUDITING
VALUES(ORA_LOGIN_USER,SYSDATE);
END;
2003 Accenture All Rights Reserved. 155
Manipulating Triggers
Altering triggers:
ALTER TRIGGER trigger_name ENABLE|DISABLE;
ALTER TABLE table_name ENABLE|DISABLE all triggers;
Dropping triggers:
DROP TRIGGER trigger_name;
The following data dictionary views reveal information about triggers:
-USER_TRIGGERS
-ALL_TRIGGERS
-DBA_TRIGGERS

2003 Accenture All Rights Reserved. 156


Packages
A package is a group of procedures, functions, variables and SQL
statements created as a single unit. It is used to store together related
objects.

A package has two parts, Package Specification or package header and


Package Body.

Package Specification acts as an interface to the package. Declaration of


types, variables, constants, exceptions, cursors and subprograms is done
in Package specifications. Package specification does not contain any
code.

Package Body is used to provide implementation for the subprograms,


queries for the cursors declared in the package specification or spec.

2003 Accenture All Rights Reserved. 157


Advantages of Packages
Package allows you to group together related
items, types and subprograms as a PL/SQL
module.
When a procedure in a package is called entire
package is loaded, though it happens to be
expensive first time the response is faster for
subsequent calls.
Package allows us to create types, variable
and subprograms that are private or public

2003 Accenture All Rights Reserved. 158


Package Header Syntax
Package <Package Name> is
[Declaration of Variables and Types]
[Declaration of Cursors]
[Specifications of modules]
End <package Name> ;

2003 Accenture All Rights Reserved. 159


Package Body Syntax
Package Body <Package Name> is
[Declarations of variables and Types]
Specification of body of module

Begin
Executable statements
[Exception]
[Exception statements]
End <Package Name> ;

2003 Accenture All Rights Reserved. 160


Example: Package Header
Create or replace Package P_Package1 as
Procedure P_Proc1;
Function P_Func1 return Varchar2;
End P_Package1;
/

2003 Accenture All Rights Reserved. 161


Example: Package body
Create of Replace Package body P_Package1 as
Procedure P_Proc1 is
begin
dbms_output.put_line(Hello from Procedure);
end P_Proc1;
Function P_Func1 return Varchar2 is
begin
return (Hello from Function);
end P_Func1;
End P_Package1;
/

2003 Accenture All Rights Reserved. 162


Example: Execute Package
SQL> Set serveroutput on
SQL> EXEC P_Package1. P_Proc1;

SQL> Select P_Package1. P_Func1 from Dual;

2003 Accenture All Rights Reserved. 163


Example2: Package Header
Create or replace Package P_Dept as
Procedure P_Insert_Dept(i_deptno number);
Procedure P_Insert_Dept(i_deptno number, i_dname varchar2, i_loc
varchar2);
Procedure P_Update_Dept(i_deptno number, i_loc varchar2);
Procedure P_Delete_Dept(i_deptno number);
End P_Dept;
/

2003 Accenture All Rights Reserved. 164


Example: Package body
Create or Replace Package body P_Dept as
Procedure P_Insert_Dept(i_deptno number) is
begin
insert into dept values(i_deptno, 'DefDname','DefLoc');
end P_Insert_Dept;
Procedure P_Insert_Dept(i_deptno number, i_dname varchar2, i_loc varchar2) is
begin
insert into dept values(i_deptno, i_dname, i_loc);
end P_Insert_Dept;
Procedure P_Update_Dept(i_deptno number, i_loc varchar2) is
begin
update dept set loc = i_loc
where deptno = i_deptno;
if sql%notfound then
dbms_output.put_line( Your error text);
end if;
end P_Update_Dept;
Procedure P_Delete_Dept(i_deptno number) is
begin
delete from dept
where deptno = i_deptno;
end P_Delete_Dept;
End P_Dept ;
/

2003 Accenture All Rights Reserved. 165


Example: Execute Package
SQL> Set serveroutput on
SQL> EXEC P_dept. P_insert_dept(90, QA,ROME);
SQL> select * from dept;
SQL> EXEC P_dept.P_insert_dept(99);
SQL> select * from dept;
SQL> EXEC P_dept.p_update_dept(90,Chn);
SQL> select * from dept;
SQL> EXEC P_dept.p_delete_dept(90);
SQL> select * from dept;

2003 Accenture All Rights Reserved. 166


DBMS_PROFILER
Since Oracle 8i we can trace pl/sql like we can trace sql
with tkprof. With DBMS_PROFILER you can measure
the execution time of a pl/sql program unit.
DBMS_PROFILER gives insight into the following
statistics:
- The number of times a piece of pl/sql was executed
- The total time spend on a piece of pl/sql code,
including sql statements.
- Minimum and maximum time spend on a piece of
pl/sql code
- Which code is executed during profiling.

2003 Accenture All Rights Reserved. 167


Prerequisites
The DBMS_PROFILER package is not
automatically created on install of the
database.
Before you can use it, you should run the
following scripts: as sys user run the
$ORACLE_HOME/rdbms/admin/profload.sql
script.
As user that uses the profiler (or as sys with
grants) run:
$ORACLE_HOME/rdbms/admin/proftab.sql

2003 Accenture All Rights Reserved. 168


Procedures
The DBMS_PROFILER package has the following
procedures:
Start_Profiler: begin data collection Stop_Profiler: stop
data collection. Data is not automatically stored when
the user disconnects.
Flush_Data: flush data collected in user session. Can
call at points in a run to get incremental data.
Pause_Profiler: pause user data collection
Resume_Profiler: resume data collection Get_Version
(proc): gets the version of this api.
Internal_Version_Check: verify that the DBMS_Profiler
version works with this DB version.

2003 Accenture All Rights Reserved. 169


Tables
The profiler-information is stored in the
following tables:
plsql_profiler_runs - information on profiler runs
plsql_profiler_units - information on each line
profiled
plsql_profiler_data - profiler data for each line
profiled

2003 Accenture All Rights Reserved. 170


Run profile session
set serverout on enabled
declare
run_id number;
begin
run_id := dbms_profiler.start_profiler(
to_char(sysdate,'DD-MM-YYYY HH24:MI:SS'));
.. call pl/sql ..
/* Clear data from memory and store it in profiler tables.*/
dbms_profiler.flush_data;
dbms_profiler.stop_profiler;
end;

2003 Accenture All Rights Reserved. 171


Report on profile session
In Oracle 8i, Oracle supplied a sql
${ORACLE_HOME}/plsql/demo/profrep.sql to report of the
profiling results.

In Oracle 10g a sql ${ORACLE_HOME}/plsql/demo/profsum.sql is


provided.
-- show procedures
SELECT substr(u.unit_type,1,30),substr(u.unit_name,1,30),
ROUND(d.total_time/10000000,2) total, d.total_occur, d.min_time,
d.max_time FROM plsql_profiler_units u, plsql_profiler_data d
WHERE u.runid = &1 AND u.unit_owner <> 'SYS' AND d.runid =
u.runid AND d.unit_number = u.unit_number AND
ROUND(d.total_time/1000000000,2) > 0.00 ORDER BY
d.total_time DESC;

2003 Accenture All Rights Reserved. 172


Top 10 Slow statements
SELECT * FROM ( select trim(decode(unit_type,'PACKAGE
SPEC','PACKAGE',unit_type)|| ' '||trim(pu.unit_owner)||'.'||
trim(pu.unit_name))|| ' (line '|| pd.line#||')' object_name ,
pd.total_occur , pd.total_time , pd.min_time , pd.max_time ,
src.text , rownum sequencenr
from plsql_profiler_units pu , plsql_profiler_data pd , all_source src
where pu.unit_owner = user and pu.runid = &1
and pu.runid=pd.runid
and pu.unit_number = pd.unit_number
and src.owner = pu.unit_owner
and src.type = pu.unit_type
and src.name = pu.unit_name and src.line = pd.line# )
where sequencenr <=10;

2003 Accenture All Rights Reserved. 173

You might also like