You are on page 1of 98

PL/SQL

=========

1. PL/SQL stands for Procedural Language extensions to the Structured Query


Language (SQL).
2. PL/SQL is a combination of SQL along with the procedural features of
programming languages.
3. Oracle uses a PL/SQL engine to processes the PL/SQL statements.
4. PL/SQL includes procedural language elements like conditions and loops.
5. It allows declaration of constants and variables, procedures and functions,
types and variable of those types and triggers.

Pl/sql Block structure


======================

Declare (optional)

decalring the variables, cursors, user defined exceptions,....

Begin (mandotary)

select ... into ---

Exception( optional)

-- handling the exceptions

End;(mandotary)

note: DDL not allowed


DML allowed
DCL not allowed
TCL allowed
DQL allowd

Plsql supported by 2 typs blocks

==================================

annonymous Block
=================

No name given to these blocks

we are not calling these blocks to client application.

not store in database

ex:

Declre

Begin

Exception
End;

named Block
===========
any name given to these blocks

These blockes calling anywhere

it stored in database

ex:
Procedures, Functions, Packages , Triggers..

DBMS_OUTPUT.PUT_LINE:
=====================

1. Oracle provided default package

2. it is used to dispaly the messages or variable values;

DBMS_OUTPUT : package

PUT_LINE : procedure

Variables:
===========

variables are used to store a value in memory localtion.

Decalring the variable:


======================
syntax:

Variable name datatype(size);

ex: decalre
a number (10);
b varchar2(20)
c date;

storing the value into variable:


===============================

using assignment operator (:= ) we are storing a value into variable.

syntax:

variable name := value;

EX1

declare
a number(10);

begin

a := 5+3;

DBMS_OUTPUT.PUT_LINE(a);

END;

ex2:

Declare

B Varchar2(30);

begin

b:= 'RAJESWARA REDDY';

DBMS_OUTPUT.PUT_LINE(B);

END;

whenever we are using not null,constant values, we have intial the value at
declation section;

Declare

A number(10) :=10;
C number(10) :=20;
B Varchar2(30):= 'RAJEH';
D number(10);

begin

D :=A+C;

DBMS_OUTPUT.PUT_LINE( B ||' ' ||D);

END;

Declare

A number(10) default 10;


C number(10) default 20;
B Varchar2(30) default 'RAJEH';
D number(10);
begin

D :=A+C;

DBMS_OUTPUT.PUT_LINE( B ||' ' ||D);

END;

SELECT INTO ===== Clause


====================

using select into clause we are retriving the values from table storing pl/sql
variables.

select into clause always return single record or single value at a time.

this clause used in begin and end of the pl/sql progra.

syntax:

select col1, col2, col3 ........ into variable1,variable2,variable3 from table


name where condition;

example:
========
declare

V_EMPNO number(10);
V_ENAME VARCHAR2(30);
V_SAL number (10);

Begin

select empno into V_EMPNO from EMP where empno=7839;

dbms_output.put_line ( 'Employee number is :' || ' '|| V_EMPNO);

END;
/

example:
========

declare

V_EMPNO number(10);
V_ENAME VARCHAR2(30);
V_SAL number (10);

Begin

select empno,ename,sal into V_EMPNO,v_ename,v_sal from EMP where empno=7839;

dbms_output.put_line ( V_EMPNO ||' '|| V_ENAME ||' '|| V_SAL );


END;
/

Varible attributes
==================

whenever we are using varible attributes in declaration of the varibales


automatically oracle server allocate memory for
corresponding datatypes with in the table.

there are two variable attributes

1. column level attributes

2. row level attribute

column level attributes


=========================

sysntax: tablename.columnname%type

declare

V_EMPNO emp.empno%type;
V_ENAME emp.ename%type;
V_SAL emp.sal%type;

Begin

select empno,ename,sal into V_EMPNO,v_ename,v_sal from EMP where empno=7839;

dbms_output.put_line ( V_EMPNO ||' '|| V_ENAME ||' '|| V_SAL );

END;
/

2. row level attribute

=====================

syntax: tablename%rowtype

EXAMPLE:
============

declare

V_EMP EMP%ROWTYPE;

Begin
select empno,ename,sal into V_emp.empno,v_emp.ename,v_emp.sal,v_emp.hiredate
from EMP where empno=7839;

dbms_output.put_line ( V_emp.empno ||' '|| v_emp.ename ||' '|| v_emp.sal||' '||


v_emp.hiredate);

END;
/

Bind variable
===============
These varibles are session variables.these values are used to pass the data
between client and database server.

we can also use these varibles with in the pl/sql

These variables are created in host environment

these varibles called host variables

generally these variables are used in pl/sql to execute procedures having


out,inout parameters

createing bind variables


=====================

syntax: variable variablename datatype

using bind variable


======================

: variable name

display the value from bind varible


===================================

print variable name

example:

variable g number;

decalre

a number(10) :=5000;

begin

:g := 5000/2;

end;
/

print g:

conditional stetements
========================

IF

1. simple IF condtion

2. IF ELSE condtion

3 elsif condtion

simple IF condtion
====================
synatx:

IF conition then
statements
end if

IF ELSE condtion
===============

IF Condition1 then
statements
ELSE
statements
END IF

elsif condtion
==================

IF Condition1 then
statements
ELSIF condition2 then
statements

ELSIF condition3 then


statements
------

ELSE
statements

END IF;

Example

===========

declare

V_DEPTNO Number(10);
Begin

select deptno into V_DEPTNO from DEPT where deptno=&no;

IF V_DEPTNO=10 then

DBMS_OUTPUT.PUT_LINE ('ten');

END IF;

END;

exp2
====

declare

V_DEPTNO Number(10);

Begin

select deptno into V_DEPTNO from DEPT where deptno=&no;

IF V_DEPTNO=10 then

DBMS_OUTPUT.PUT_LINE ('ten');

ELSE

DBMS_OUTPUT.PUT_LINE ('other');

END IF;

END;
/

EXP3:
====

declare

V_DEPTNO Number(10);

Begin

select deptno into V_DEPTNO from DEPT where deptno=&no;

IF V_DEPTNO=10 then

DBMS_OUTPUT.PUT_LINE ('ten');

ELSIF V_DEPTNO=20 then


DBMS_OUTPUT.PUT_LINE ('Twenty');

ELSIF V_DEPTNO=30 then

DBMS_OUTPUT.PUT_LINE ('Thirty');

ELSE

DBMS_OUTPUT.PUT_LINE ('others');

END IF;

END;

Control Statements
=================

1 simple loop

2 while loop

3 For loop

Body of the statements executed repeatedly . this loop also call infinite loop

simple loop

==========================

loop

statements;

end loop;
/

ex:

Begin
loop
dbms_output.put_line('welcome');

end loop;
end;

To exit infinte loop we are using following method

method 1: IF condition

ex:

declare
n number (10) :=1;

begin
loop

dbms_output.put_line (n);

IF n>=100 Then
Exit;
End if;
n:=n+1;
end loop;

end;

method 1: Exit when true condtion

ex:

declare

n number (10) :=1;

begin
loop

dbms_output.put_line (n);
exit when n>=0;
n:=n+1;
end loop;

end;

While loop
========

here body of the statements executed repeatedly untill condition is true.

syntax:
=======

while condition
loop
statements
end loop

ex1:

declare
n number (10) :=1;

begin
While a<=10
loop
dbms_output.put_line (n);
n:=n+1;
end loop;
end;
/

For loop
=======

Stntax:

For loop varible in lower bound ...... upper bound

Loop
statements;

End;

Example;
-------

declare

n number (10) :=1;

begin

For n in 1..10
loop

dbms_output.put_line (n);
end loop

end;

ex:

declare

n number (10) :=1;

begin

For n in reverse 1..10


loop

dbms_output.put_line (n);
end loop;

end;

Cursor
======

to process multiple records

record by record process

Curser is an private memory area is used to process multiple records and also these
records process is record by record.

static cursor

dyanamic cursor (ref cursor) -- will explain advanced collection

There are 2 types of static cursors supported by Oracle

1 implicit curor

2 explicit cursor

implicit curor
===============

For sql statements returns single record is called implicit cursor.

Implicit cursors are simple pl/sql prograns which contains select --- into clause
or DML statements.But these records are process
at a time.

wheneverwe are using in pl/sql block auto matically oracle server created an
memory area. these memory area also called context area or
Implici cursor.

Ex:

Declare

I EMP%ROWTYPE;

BEGIN

SELECT * INTO I FROM EMP where EMPNO=&NO;

DBMS_OUTPUT.PUT_LINE ( I.EMPNO ||' '|| I.ENAME ||' '|| I.SAL|| ' '|| I.DEPTNO);

END;
/

EX2:

Declare

I EMP%ROWTYPE;

J DEPT%ROWTYPE;
BEGIN

SELECT E.EMPNO,E.ENAME,E.SAL,E.DEPTNO,D.DNAME,D.LOC INTO


I.EMPNO,I.ENAME,I.SAL,I.DEPTNO,J.DNAME,J.LOC FROM EMP E,DEPT D where
E.DEPTNO=D.DEPTNO and E.EMPNO=&NO;

DBMS_OUTPUT.PUT_LINE ( I.EMPNO ||' '|| I.ENAME ||' '|| I.SAL|| ' '|| I.DEPTNO ||
' ' || J.DNAME||' '|| J.LOC);

END;
/

Explicit cursor
===============

For sql statements returns multiple rows is called explicit cursors.

set of rows return by a select statement is called 'Active set area" (internal
memory area).

Explicit cursor life cycle


=============================

Declare
Open
fetch
close

Dclare:
======

In declaration section of pl/sql programs. we are define the declare using


following syntax

syntax:

cursor cursorname is select statement;

Open
====

whenever we are opening the cursor set of rows return from table into cursor.

synatx:

Open Cursorname

Note: whenever we are open the cursor cursor pointer point the first record in the
cursor.

Fetch:(fetching from the cursor)


======

we are fetching data from cursor into pl/sql variables.


synatx:
==========

fetch cursorname into variable names

Close
=======

whenever we are closing the cursor all the resources allocated from the cursor
memory are released.

synatx:

close cursor name

ex:
==

Declare

V_ename varchar2(30);

V_sal number(10);

cursor C1 is select ename,sal from emp;

Begin

open c1;

fetch c1 into V_ename,v_sal;

DBMS_OUTPUT.PUT_LINE(V_ename ||' '|| v_sal);

Close c1;

End;

ex:
==

Declare

V_ename emp.ename%type;

V_sal emp.sal%type;

cursor C1 is select ename,sal from emp;

Begin

open c1;
fetch c1 into V_ename,v_sal;

DBMS_OUTPUT.PUT_LINE(V_ename ||' '|| v_sal);

Close c1;

End;

ex:
==

Declare

V_emp emp%rowtype;

cursor C1 is select ename,sal from emp;

Begin

open c1;

fetch c1 into v_emp.ename,v_emp.sal;

DBMS_OUTPUT.PUT_LINE(v_emp.ename ||' '|| v_emp.sal);

Close c1;

End;

EXplict cursor attributes


------------------------

every explicit cursor having following 4 attributes

1. %not found
2. %found
3. % is open
4. %row count

always these attributes are used along with cursor name only.

except %row count all other curor attributes return boolean value either true or
false

synatx:

cursorname % attribute name

ex:

Declare
v_name varchar2(30);
v_sal number(10);

cursor c1 is select ename, sal from emp;

Begin
open c1;
loop
fetch c1 into v_name, v_sal;
exit when c1% notfound;
DBMS_OUTPUT.PUT_LINE(v_name||' '|| v_sal);
end loop;
close c1
End;
/

disply first 5 salaries employess wsing cursor ?

declare

cursor c1 is select ename,sal from emp;

v_name varchar2(30);

v_sal number(10);

Begin
open c1;
loop
fetch c1 into v_name,v_sal;

dbms_output.put_line(v_name ||' '||v_sal);


exit when c1%rowcount>=5;

--dbms_output.put_line(v_name ||' '||v_sal);

end loop;

close c1;

End;
/

ex:write pl/sql cursor to transfer ename, salary of who are getting more then
2000?

Declare

cursor emp_cur is select * from emp where sal>2000;

i emp%type;

n number(10);

begin
n:=0;
open emp_cur;
loop

fetch emp_cur into i;

when emp_cur%notfound;

n:=emp_cur%rowcount;

insert into Target values(n, i.ename,i.sal);

end loop;

close emp_cur;

end;
/

Eliminating the cursor life cycle


=================================

using cursor For loop we are eliminating the cursor lifecycle

syntax:

for variable name in cursor name;


loop
--
--
end loop;

note: alway for loop index variable internally behave like a record type
variable(%rowtype)

whenever we are using cursor for loop no need to explicitly open, fetch and close

expmple;
-----------

declare

cursor C1 is select * from emp where sal>2000;

begin

for i in c1

loop

exit when c1%notfound;

dbms_output.put_line(i.ename||' '|| i.sal);

end loop;

end;
/

note: we can also elimate the declaration section of cursor using cursor for loops.
In this we can use select statement inplace of cursor name.

EX

begin

for i in (select * from emp where sal>2000)

loop

dbms_output.put_line(i.ename||' '|| i.sal);

end loop;

end;
/

parameterizied cursor
=======================

we are passing formal parameters in ursor declaration and we are passing actual
parameters in open curor.

syntax:

cursor cursorname(formal parameters) is select statement where condition

open cursor name(actual parameters)

ex:

declare

cursor C1(P_DEPTNO NUmber) is select * from emp where deptno=P_DEPTNO;

i emp%rowtype;

begin

open C1(10);

Loop

fetch c1 into i;
exit when c1%notfound;

dbms_output.put_line(i.ename ||' '|| i.deptno||' '||i.sal);


end loop;

close c1;
end;
/

ex: write pl/sql program employess working under manager

Declare

cursor c1 (p_job varchar2) is select * from emp where job=p_job;

i emp%rowtype;

begin

dbms_output.put_line('employee working under manager');

OPEN C1('MANAGER');

loop

Fetch C1 into i;

exit when c1%notfound;

dbms_output.put_line(i.ename);

end loop;

close c1;

dbms_output.put_line('employee working under analyst');

OPEN C1('ANALYST');

loop

Fetch C1 into i;

exit when c1%notfound;

dbms_output.put_line(i.ename);

end loop;

close c1;

end;
/

ex2:

Declare

cursor c1 (p_job varchar2) is select * from emp where job=p_job;

i emp%rowtype;
V_job varchar2(30);

begin

begin

select job into V_job from emp where job='MANAGER' and rownum=1;
end;

dbms_output.put_line('employee working under manager');

OPEN C1( V_job);

loop

Fetch C1 into i;

exit when c1%notfound;

dbms_output.put_line(i.ename);

end loop;

close c1;

begin

select job into V_job from emp where job='ANALYST' and rownum=1;
end;

dbms_output.put_line('employee working under analyst');

OPEN C1( V_job);

loop

Fetch C1 into i;

exit when c1%notfound;

dbms_output.put_line(i.ename);

end loop;

close c1;

begin

select job into V_job from emp where job='CLERK' and rownum=1;
end;

dbms_output.put_line('employee working under CLERK');

OPEN C1(v_job);

loop

Fetch C1 into i;
exit when c1%notfound;

dbms_output.put_line(i.ename);

end loop;

close c1;

end;
/

exp : write a pl/sql cursor program to display emplyee details and total salary
department wise?

declare

cursor c_emp is select * from emp;

cursor c_dept is select * from dept;

v_sal emp.sal%type;

begin

for i in c_dept

loop

v_sal :=0;

dbms_output.put_line('---------------------------');

dbms_output.put_line(i.dname||' '|| i.deptno);

dbms_output.put_line('---------------------------');

for j in c_emp
loop

if i.deptno=j.deptno then

v_sal:= v_sal+j.sal;

dbms_output.put_line(j.ename||' '|| j.job||' '|| j.deptno||' '||j.sal);

end if;
end loop;
dbms_output.put_line('total sal for department'|| ' '||i.dname || ' '||
V_sal );
end loop;
end;
/

ex : wrong

declare
cursor c_emp is select * from emp;

cursor c_dept is select * from dept;

v_sal emp.sal%type;

begin

for i in c_emp
loop

v_sal :=0;

dbms_output.put_line('---------------------------');

dbms_output.put_line(i.ename||' '|| i.deptno);

dbms_output.put_line('---------------------------');

for j in c_dept
loop

if i.deptno=j.deptno then

v_sal:= v_sal+i.sal;

dbms_output.put_line(j.dname||' '|| v_sal);

end if;
end loop;
end loop;
end;
/

%found
======

this attribute return boolen value either true or false.

if cursor having data it return true

ex:

set SERVEROUTPUT ON;

declare

cursor C1 is select * from emp where job=&job;

i emp%rowtype;

n number(10):=0;

Begin

open c1;
loop

fetch c1 into i;

exit when c1%notfound;

if c1%found then
n:=n+1;
end if;
end loop;
close c1;

if n>0 then

dbms_output.put_line('No of jobs are' ||' '|| n);

else

dbms_output.put_line('No such jobs');

end if;

end;
/

For update , where current clauses


==================================

genarally whenever we are using update, delete satemants oracle server establish
the locks automatically

If want establish locks before update ,delete then only we are using explicit
locking mechanisim through for update clause.

After perform the activity we have to use commit/roolback to release locks.

syntax:

cursor cursor name is select statement condition For update no wait;

where current of clause


=====================
if want update or delete rows genarally we are using primary key but insted of
this one Cursor provided an other mechanisim
where current clause.

where current of clause hold the most recently updated , deleted records from
cursor because internally where current Clause
works as Rowid only.

where we are where current of clause we must use for update clause.

synatx:

cursor cursor name is select * from tablename where condition for update no wait
update tablename set coulmnname= modified value where current of cursorname

ex:

cursor c1 is select * from emp for update nowait;

i emp%rowtype;

Begin
open c1;
loop
fetch c1 into i;
exit when c1%notfound;

IF i.JOB ='CLERK' THEN

update emp set sal=sal+100 where current of c1;

ELSIF I.JOB='SALESMAN' THEN

update emp set sal=sal-100 where current of c1;


ELSE
update emp set sal=sal+200 where current of c1;

END IF;
END loop;
commit;
CLOSE C1;
End;
/

Implicit cursor attibuts


========================
Every implicit cursor attibutes having following 4 attributes.

sql%notfound

sql%found

sql%isOpen

sql%rowcount

These attributes are used whenevr dml operations performed on the pure pl/sql
programs;

note: sql%isopen return alway false

Exceptions
==========

Exception is an error occur during runtime.

pl/sql support 3 types of exceptions

1. predefined exceptions
2. user defined exceptions
3. unnamed exceptions

Predefined exceptions
======================

Oracle defined 20 Predefined exception names for regularly occured error

1. No_data_found
2 too_many_rows
3 Zero_DIVIDE
4. Invalid cursor
5 value_error
6 cursor _already_open
7 dul_val_on_idex
8 invalid_number

------
---
etc

when ever error occurs use appropriate exception names in exception hadler under
exception section/block

synatx:

when exception name then


statements
when exception name then
statements

-------------------
------------------

When Other Than


statements

No_data_found
=============

wheanever we are using select into clause if requested data not available oracle
server voilets an error : ORA:01403 No data found;

To handle this error we are using 'No_DATA_FOUND' exception

Ex:

Declare

V_Name emp.ename%type;

BEGIN

select ename into v_name from emp where ename=&name;


DBMS_OUTPUT.put_line(V_name);

Exception

WHEN NO_DATA_FOUND THEN

DBMS_OUTPUT.put_line('Requested employee not available');

END;
/

Note:
=======
when ever we are using DML statements with in the pl/sql block if requested data
not available also oracle server not return
any error. if want handle the one using inplicit cursor attibutes.

ex:

Begin

delete from emp where ename='RAJESH';

if sql%found then
dbms_output.put_line ('Your record deleted ');
end if;

if sql%notfound then
dbms_output.put_line ('Your record not exits ');
End if;
End;
/

too_many_rows
=============
when ever select into clause trying to return more tgan one row oracle server
violets an error ORA-01422: exact fetch return more Than
requested number of rows

if we handle this error using 'TOO_MANY_ROWS' exception

ex:

Declare

i emp%rowtype;

Begin

select ename, sal into i.ename,i.sal from emp where Job=&JOB;

dbms_output.put_line(i.ename ||' '|| i.sal);

EXCEPTION
WHEN TOO_MANY_ROWS THEN

dbms_output.put_line('not return more than one value');


END;
/

Invalid_Cursor
===============

IF we are not performing proper operations on the cursor the oracle server return
error invalid Cursor

if we not opening the cursor also whn trying to close the cursor to handle the
exception using 'INVALID_CURSOR'

ex:

Declare

Cursor c1 is select * from emp where sal>2000;

i emp%rowtype;

Begin

loop

fetch c1 into i;

exit when C1%notfound;

dbms_output.put_line(i.ename ||' '|| i.sal);


end loop;
close C1;

EXCEPTION

WHEN INVALID_CURSOR THEN

dbms_output.put_line('Cursor must be open');

end;

invalid_number,value_error
============================
when ever we are try to convert string to number oracle server voilets errors
invalid number , value error .

if our pl/sql blocks contains sql staements and try to convert string to number
oracle server voilets error .
to handle this error using 'INVALID_NUMBER' exception.

If our pl/sql blocks contains pure pl/sql staements and try to convert string to
number oracle server voilets error .
to handle this error using 'VALUE_ERROR' exception.

EXMPLE:
========
Declare
V_DEPTNO VARCHAR2(10) :='&DEPTNO';
V_NAME varchar2(10) :='&DNAME';
V_LOC VARCHAR2(10) := '&LOC';

Begin

Insert into DEPT values (V_DEPTNO,V_NAME,V_LOC);

EXCEPTION
WHEN INVALID_NUMBER THEN

dbms_output.put_line('enter proper data');

END;
/

DECLARE

Z number(10);

begin

z := '&x'+'&y';
DBMS_OUTPUT.put_line(z);
EXCEPTION
WHEN VALUE_ERROR THEN

dbms_output.put_line('enter valid data');

end;
/

User defined Exceptions


========================

We can also create our own exceptions and also raise wheanever necessary using
following setps.

steps:

declare

raise

exception handler

Declare
=========

In declaration section of PL/SQL block we are creating our own Exception using
exception type.

syntax: user defined name Exception


raise
=======

whenever necessary we are raising the Exception either begin or exception section
using raise stetement.

synatx: raise Exception name

Exception handler
================

we can also handle the user defined Exception same as predifined Exception using
Exception handler.

synatx:

Exception

when user defined Exception name Than


statements

when user defined Exception name Than


statements

-------

EX
---- Write a PL/SQL program raise an Exception today;

Declare

Z Exception;

Begin

If to_char(sysdate,'DY')='MON' Then
raise z;
end If;
Exception

when z Then

DBMS_OUTPUT.PUT_LINE('exception raised today');

end;
/

ex:

Declare

V_sal emp.sal%type;

z exception;

Begin
select sal into V_sal from emp where empno=7839;

If V_sal >4000 Then

raise z;

else
update emp set sal=sal+100 where empno=7839;
end if;

Exception

when z Then

dbms_output.put_line('salary greter than 4000');

end;

Raise application error


========================

This is a predifined function used to display message as same as oracle error


displed format.

Genarally this function is used in triggers because wheanever conditions is there


immidiatly raises a message and also
according to conditions it stops invalid data entry.

synatx:
-20000 to -20999
Raise_application_error(errornumber,message');

EX

ex:

Declare

V_sal emp.sal%type;

Begin

select sal into V_sal from emp where empno=7839;

If V_sal >4000 Then

Raise_application_error(-20123,'salary gretar than 4000');

else
update emp set sal=sal+100 where empno=7839;
end if;

end;
/

SQLcode, SQLERRM
=================

These Predefined functions used to test the status of the Pl/sql block and also
catch the error number and error messages.

- sql code returns some numbers


- sql errm returns error number with error message

sql code retun values:

retun value meaning


========== =========
0 no error
-ve oracle error
100 no data found
1 user defined exception

ex:

declare
v_sal emp.sal%type;

Begin

select sal into v_sal from emp;

dbms_output.put_line(v_sal);

Exception

WHEN OTHERS Then

dbms_output.put_line(sqlcode);

end;
/

output: -1422

ex:

declare
v_sal emp.sal%type;

Begin

select sal into v_sal from emp where ename ='RAJESH' ;

dbms_output.put_line(v_sal);

Exception

WHEN OTHERS Then

dbms_output.put_line(sqlcode);

end;
/

output: 100

ex:

declare

z Exception;

Begin

raise z;

Exception
when z Then

dbms_output.put_line(sqlcode);

end;
/
output: 1

Note: whenever we are using sqlcode,sqlerrm in programing. we are not allowed to


use directly inplace of this one.

we are declaring the Variables and assigned values into Variables and used this
variables in programing.

ex: write a Pl/sql program store sqlcode,sqlerrm return values into a saparate
table.

---Create table h1 (error_number number(10), error_message varchar2(200));

DECLARE
l_msg VARCHAR2(255);
l_sal emp.sal%type;
l_no number(10);
BEGIN
SELECT sal INTO l_sal FROM emp;

EXCEPTION
WHEN OTHERS THEN
l_no := SQLCODE;
l_msg := SQLERRM;
dbms_output.put_line(l_no ||' ' ||l_msg);
insert into h1 values(l_no,l_msg);
END;
/

Unnamed exceptions
===================
Other than oracle 20 predefined exceptions are handle using unnamed method only.
oracle 20 predefined exception names inplace of this one we are creating our own
exception using exception type and also
associate error number using Exception_init.

syntax: Pragma exception_init(user defined exception name, error number);

Here pragma is an compiler directive

i.e oracle server identify the error at the time of compilation only.

This function is used in declar section of the pl/sql programs

All DBA error handling using this method only

ex:

declare

z exception;

pragma exception_init(z, -2292);

Begin
delete from dept where deptno=10;

exception
when z then
dbms_output.put_line('not to delete master record');
END;
/

--- write pl/sql program using un named method handle -2291 error

declare

z exception;

pragma exception_init(z, -2291);

Begin
insert into emp (empno,deptno) values(5,55);

exception
when z then
dbms_output.put_line('not insert other than primaray key values');
END;
/

note: we can also impliment unnamed method using sqlcode

Begin
insert into emp (empno,deptno) values(5,55);

exception
when others then
if sqlcode=-2291 then

dbms_output.put_line('not insert other than primaray key values');

end if;
END;
/

sub programs:
-------------
Sub programs are named pl/sql blocks. used to solve some particlar tasks.There are
2 types of sub programs supported by Oracle.

1. Procedures

2. Functions

1. Procedures
===============

Procedures are named Pl/sql blocks used to solve some particular tasks.Procedures
are may or may not return a value.

Genarally Procedures are used to improve the performence of the application because
first time only number of statements with in the Procedures
are comipled.

i.e oracle server internally stores p_code compiled format.

whenever creating the procedures we are create or replace beyond infront of the
procedures. Those procedures are stored In

database. these procedures called stored procedures

procedures having 2 parts

1. procedure specification
2. procedure Body

In procedure specification we are specifining name of procedure , type of


parameters.

where as procedure body we are solving actual tasks

syntax:

create or replace

procedure procedure name ( formal parameters)

IS/AS
Variabledeclaration, cursor declaration, user defined exceptions

Begin
---
--- procedure body
---

[exception]

end;
/

Formal parameters decalaration


=============================

parameter name [mode] datatype

In
out
INOUT

excuting methods:

----------------

method1

exec procedure name (atual parameters)

method2
--------

using annonymous Block

Begin

procedure name (atual parameters)

end;

ex: develop a pl/sql stored procedure for passing EMPNO to display employee name
and salary;

create or replace procedure XXRR_EMPLOYEE( P_EMPNO NUMBER)

is

V_ENAME emp.ename%type;
V_sal number(10);

Begin

select ename, sal into v_ename, v_sal from emp where empno=P_EMPNO;

dbms_output.put_line( 'employee name is' ||' '||v_ename);

dbms_output.put_line( 'employee Salary is' ||' '||v_sal);


Exception

when No_data_found Then

dbms_output.put_line(' eemployee does not exits');

End;
/

Excution method1

exec XXRR_EMPLOYEE(123);
/

Excution method2

begin
XXRR_EMPLOYEE(7839);
end;

note: all procedures stored user_source

-- develop a Pl/sql stored procedure to insert a record into DEPT table using
formal parameters:

create or replace procedure XXRR_EMPLOYEE1( P_DEPTNo IN NUMBER,


P_DNAME IN VARCHAR2 ,
P_LOC IN
VARCHAR2)

is

Begin

Insert into DEPT values(P_DEPTNo,P_DNAME, P_LOC);

dbms_output.put_line( 'Record insertrd sucessfully');

Exception

when others Then

dbms_output.put_line('record not inserted');

End;
/

IN
=====

It is used to pass values into sub programs. IN mode basically like a constant in
procedure body.

By default mode is IN mode, Though IN mode we are passing default values in to


procedure

In this case we are using default keyword

syntax: parameter name [IN] datatype [default] actual value;

ex: write a Pl/sql stored procedure using in parameters store a record in dept
table and also used default location?

create or replace procedure XXRR_EMPLOYEE2( P_DEPTNo IN NUMBER,


P_DNAME IN VARCHAR2 ,
P_LOC IN
VARCHAR2 default 'HYD')

is

Begin

Insert into TEST_DEPT values(P_DEPTNo,P_DNAME, P_LOC);

dbms_output.put_line( 'Record insertrd sucessfully');

Exception

when others Then

dbms_output.put_line('record not inserted');

End;
/

Note: there are 3 types of exceution septs suppoted by IN parameters

1. potion notation

2 . named notations

3. combination noatations

position notation
==================
exec XXRR_EMPLOYEE2(20,'SALES','BAN');

Named notations
===================
exec XXRR_EMPLOYEE2( P_DEPTNO =>30,P_DNAME =>'SALES',P_LOC =>'DHI');

exec XXRR_EMPLOYEE2( P_LOC =>'MUM',P_DEPTNO =>40,P_DNAME =>'MARKETING');

Combination Notation
===================
exec XXRR_EMPLOYEE2( P_LOC =>'MUM'40,P_DNAME =>'MARKETING'); -- Not working

exec XXRR_EMPLOYEE2(40, P_LOC =>'MUM',P_DNAME =>'MARKETING'); -- working


because starting we are using postion noations

exec XXRR_EMPLOYEE2(40, P_LOC =>'MUM','MARKETING'); - not working because


potion notations not used startig

exec XXRR_EMPLOYEE2(40,'MARKETING', P_LOC =>'MUM'); -- it is workin

out
====
It is used to return values from the sub programs.

OUT parameters internally behavious like a un intiallized Variable in procedure


boday

Here explicitly we are specifying the out keyword

synatx: Parameter name out datatype

create or replace procedure p1 (a in number,b out number)

is
Begin

b:=a*a;

end;

a:= b*b not work because a is IN parameter.

exec p1(10,b) -- not working

note: whenever we are using OUT or INOUT modes in sub programs are excuting
following 2 methods.

method1 : bind varble method


==============================

VARIABLE z number;

exec p1(10,:Z);

print z;

output: 100

method2: annonymous block


==============================

Declare
x number(10);
begin
p1(10,x);

dbms_output.put_line(x);

end;

output: 100

inout
=====
This mode internally behavious constant , intialized variable. Here also explicitly
we are sprcify INOUT Keyword.

synatx: Parameter name INOUT datatype

create or replace procedure p2 (a in out number)

is
Begin

a:=a*a;

end;

Bind variable method


======================

VARIABLE x number;

exec :x:=10;

exec p2(:x);

print x;

annonymous blockes
========================

declare

x number(10);

Begin
x:=10;

p2(x);

DBMS_OUTPUT.PUT_LINE(x);

end;
/

?
-- write a pl/sql stored procedure for passing empno return salary using INOUT
parameter?

create or replace procedure p3 (p_sal IN OUT number);

IS

Begin

select sal into p_sal from emp where empno=p_sal;

dbms_output.put_line(p_sal);

end;
/

method1
=======

VARIABLE x number;

exec :x:=7839;

exec p3(:X);

PRINT x;

method2
========

declare

z number(10);

begin
z:=7839;

p3(z);

DBMS_OUTPUT.PUT_LINE(z);
end;

Pass by value and pass by reference


=====================================

NO Copy
===========

syntax: Parameter name out nocopy datatype

Ex
===

create or replace procedure p5 (p_name IN varchar2,p_sal OUT number)


IS

Begin

select sal into p_sal from emp where ename=p_name;

dbms_output.put_line(p_sal);

end;
/

create or replace procedure p6(p_name IN varchar2,p_sal OUT NOCOPY NUMBER)

IS

Begin

select sal into p_sal from emp where ename=p_name;

dbms_output.put_line(p_sal);

end;
/

variable l_sal number;

exec p5('SMITH',:l_sal);

print l_sal;

select * from emp;

set serveroutput on;

declare

l_sal number(10);

begin

p5 ('SMITH',l_sal);

dbms_output.put_line(l_sal);
end ;
/

cursors used in procedures


=====================

create or replace procedure XXRR_CUR_TEST( P_DEPTNO number)


IS

curor c1 is select * from emp where deptno=p_DEPTNO;

i emp%rowtype;

BEGIN

OPEN c1
loop

fetch c1 into i;
exit when c1%notfound;

DBMS_OUTPUT.PUT_LINE(i.ENAME || ' '|| i.ENAME||' '||i.sal||' '||i.deptno);

DBMS_OUTPUT.PUT_LINE('*****************************************************');
end loop;
close c1;

Exception

when others then

DBMS_OUTPUT.PUT_LINE (' data not available');

END:
/

Handle or unhandle Exceptions


===============================
wheanever we are calling procedure with in an other procedure we must implement
inner procedure exception handler

otherwise oracle server call outer procedure Exception handler

ex:

create or replace procedure p7( a number, b number)


is

Begin

DBMS_OUTPUT.PUT_LINE(a/b);

EXCEPTION

when Zero_DIVIDE then

DBMS_OUTPUT.PUT_LINE('cannot be zero');

END;

create or replace procedure p8


is
Begin

DBMS_OUTPUT.PUT_LINE('--------');

P7(5,0);

EXCEPTION

when others then

DBMS_OUTPUT.PUT_LINE('INNER procedure exception handler');

END;
/

exec p8;

authid current_user
=======================
this claue is used in sub programs . Genarally if we ant read the data from the
table and perform som dml operations
and provide security based on data we are using authid current_user clause in
before IS/AS

if we want give the privailization for procedure to an other user .

ex:

create or replace procedure p9 (p_empno number)

Authid current_user

IS

i emp%rowtype;

Begin

select ename, sal , empno into i.ename, i.sal,i.empno from emp where
empno=p_empno;

DBMS_OUTPUT.PUT_LINE(i.ename);

end;
/

Pragma Auonomus_tranaction
============================

These transactions are used in either sub programs or triggers.

these transactions are independent transactions.whhenver we are performing commit


or rollback in main transaction will be not effected.

In a sub programs , triggeres are autonamous in this trancation we are using Pragma
autonomus_transaction
this Pragma is used in decalaration section of the Pl/sql programs

wheanever we are using pragma Auonomus_tranaction we must use commit or roll back.

synatx: Pragma Auonomus_tranaction

create table TEST_COUN(country varchar2(20));

create or replace procedure p9

is

begin

insert into TEST_COUNTRY values ('INDIA');


insert into TEST_COUNTRY values ('PAK');

commit;

End;
/

begin
insert into TEST_COUNTRY values ('ABC');

p9;
rollback;
end;

create or replace procedure p10

is

PRAGMA autonomous_transaction;
begin

insert into TEST_COUN values ('INDIA');


insert into TEST_COUN values ('PAK');

commit;

End;
/

begin
insert into TEST_COUN values ('XYZ');
p10;

ROLLBACK;
end;
/
select * from TEST_COUN;

1. FUNCTIONS
===============

Functionsare named Pl/sql blocks used to solve some particular tasks and also
return sigle value;

whenever creating the Functions we are using create or replace beyond infront of
the function. Those functions are stored In

database. these functions also called stored functions

functions having 2 parts

1. function specification
2. function Body

In function specification we are specifining name of function , type of parameters.

where as function body we are solving the actual tasks

syntax:

create or replace function function name (formal Parameters)


return datatype
IS/AS

variable,cursors ...

Begin
---

----
return expression;

end;

create or replace function F( a varchar2)


return Varchar2
IS
Begin
return A;
end;
/

method1
======

select F('RAJESWARA REDDY') from dual;


set serveroutput on;

method 2
=======

Declare

z varchar2(200);

Begin

Z:=F('RAJESWARA REDDY');

DBMS_OUTPUT.PUT_LINE(z);
end;

method 3
=========

variable z varchar2(200);

exec :z:=F('RAJESWARA REDDY');

print z;

method 4
-------

exec DBMS_OUTPUT.PUT_LINE(F('RAJESWARA REDDY'));

Method5
======

begin
DBMS_OUTPUT.PUT_LINE(F('RAJESWARA REDDY'));
end;

ex
write a stored function for passing employee number return gross salary based on
following condtions.

hra 10% of salary


DA 30% of salary
PF 40% of salary

gross: salary+hra+DA+PF

create or replace F1 ( P_EMPNO NUMBER)

RETURN number
IS

V_SAL number(10);

V_HRA number(10);

V_DA number(10);
V_PF number(10);

GROSS number(10);

Begin

select sal into V_SAL from EMP where empno=P_EMPNO;

V_HRA :=V_SAL*0.1;
V_DA :=V_SAL*0.3;
V_PF :=V_SAL*0.4;

GROSS :=V_SAL+V_HRA+V_DA+V_PF;

RETURN GROSS;

END:
/

select F1(7839) from Dual;

output: 9000

OUT Parameter
=============

If you want return more values using out mode.

Ex: write a stored function for passing deptno and return dname and Loc?

Create or replace function F2(P_deptno IN number,p_dname OUT VARCHAR2,P_LOC OUT


varchar2)
return varchar2

IS

Begin

select dname, loc into p_dname,P_LOC from dept where deptno=p_deptno;

return p_dname;

end;

excution:
----------

variable a varchar2(20);

variable b varchar2(20);

variable c varchar2(20);

exec :a := F2(30,:b,:c);
print b c;

Note: we can also user defined functions same like a perdufine aggrigate
functions and also these functions applied in
select satement.

---WM_Concat

ex: develop a pl/sql stored function to calculate tax for passing emp number and
also use folloeing conditions

if annalsal > 20000 tax 30%

if annalsal >15000 tax 20%

iF annalsal > 10000 tax 10%

create or replace Function F4 (P_EMPNO number)


return number
IS

V_sal number(10);

annalsal number(10);

IT number(10);

Begin

select sal+ nvl(comm,0) into V_sal from emp where empno=p_empno;

annalsal := V_sal*12;

IF annalsal >10000 and annalsal<15000 THEN

IT:=annalsal*0.1;

ELSIF
annalsal >15000 and annalsal<20000 THEN

IT:=annalsal*0.2;

ELSIF annalsal >20000 THEN

IT:=annalsal*0.3;

ELSE
IT:=0;

END IF;

RETURN IT;

end;
/
execute
========

select F4(7900) from dual;

Triggers
=========

Tiggers are also same as procedures and stored in database.It will automatically
invoked or fired wheanever
dml operations performed against tables or views.

There are 2 types of triggers supported by Oracle

1. statement level triggeres

2. row level triggers

staement level triggers are fired only once for a table where as row level
triggers fired for each row for a table.

synatx:

create or replace trigger trigger name

before/after insert/update/ delete on table name/view name

For each row (row level trigger)

WHEN(conditions)

declare

variables, cursors, user defind Exceptions


Begin

-- trigger body
--
end;

Row level triggers are excuted for every row for a table.
i. e we are using for each row clause in triggers and also data internally stored
in rollback segment

qualifires(:new,:old)

except when clause alway we are using these qualifires along with : prefix

synatx:

:new.column name
or
:old.column name
Insert Update Delete
: new yes yes no
: old no yes yes

ex. wrete a trigger on emp table when ever user insrt a record salary should be
more than 5000.

create or replace trigger tr10

before insert on XX_EMP

for each row

Begin

if :new.sal<5000 THEN

Raise_application_error (-20853,'can not insert below 5000 salary on emp table');

end if;
end;
/

insert into xx_emp (empno,sal) values(2,2000);

Using when clause:


===================

ex:

create table xx_test10 (job date);

create or replace trigger tr11

after insert on xx_emp

for each row

when (new.job ='CLERK')

Begin

insert into xx_test10 values(sysdate);

end;

/
insert into xx_emp (empno,job) values(3,'CLERK');

select * from xx_test10;

note: using Pragma Auonomous_tranaction

create or replace trigger tr11

after insert on xx_emp

for each row

when (new.job ='CLERK')


declare

PRAGMA autonomous_transaction;

Begin

insert into xx_test10 values(sysdate);

ROLLBACK;

end;

insert into xx_emp (empno,job) values(3,'CLERK');

commit;

select * from xx_test10;

ex: write a Pl/sql trigger on emp table not to perform dml operations in saturday
and sunday?

create or replace trigger tr12

before insert on XX_EMP

Begin

IF To_char(sysdate,'DY') in ('SAT','SUN') Then

Raise_application_error(-20345,'we cannot perform dml operationsin sat and sun');

end if;

end;

/
Triggering events
---------------

these events are used to writting conditions on multiple tables in a trigger body.
these clauses are used in either row level or statement level triggers.

1. inserting
2. updating
3. deleting

syntax:

IF inserting THEN

statements

ELSIF updating THEN


staements

ELSE deleting THEN

staements

END IF

write a Pl/sql trigger on employee table not perform any dml operations?

create table XX_EMP1 as select * from emp;

select * from XX_EMP1;

create or replace trigger tr13

before insert or update or delete on XX_EMP1

Begin

if inserting then

Raise_application_error(-20123,'we cannot perform insertion on emp table');

elsif updating then

Raise_application_error(-20123,'we cannot perform updation on emp table');

elsif deleting then

Raise_application_error(-20123,'we cannot perform deletion on emp table');

end if;

end;
/

insert into xx_emp1 (empno,job) values(6,'CLERK');

update xx_emp1 set sal=sal+100 ;

delete xx_emp1;

drop trigger tr13

ex2 : write a Pl/sql trigger an employee


table wheanever user inserting data these rows are stored in an other
table.wheanever updating the date thesre rows are
stored in an other table.wheanever deleting the data these rows stored in an other
table.

create table RR1 (sno number(10), name varchar2(30));

create table RR2 (sno number(10), name varchar2(30));

create table RR3 (sno number(10), name varchar2(30));


/

create or replace trigger tr13

after insert or update or delete on XX_EMP1

for each row

Begin

if inserting then

insert into RR1(sno,name) values (:new.empno,:new.ename);

elsif updating then

insert into RR2(sno,name) values (:new.empno,:old.ename);

elsif deleting then

insert into RR3(sno,name) values (:old.empno,:old.ename);

end if;

end;

/
insert into xx_emp1 (empno,ename) values(7,'CLERK');

update xx_emp1 set sal=sal+100 ;

delete xx_emp1;

select * from rr1;

select * from rr2;

select * from rr3;

Auto Increment
==============

In oracle we are genarating primary key and unique key values automatically we are
using auto incement concept.

In auto Increment concept we are using sequences in triggeres(row level triggers).

i .e explicitly we have to create sequences and use these sequences in Pl/sql


programs.

ex:

create sequence S5
start with 1
Increment by 1;

/
create or replace trigger tr14

before insert on XX_EMP1


for each row

Begin

select S5.nextval into :new.empno from dual;

end;
/

insert into XX_EMP1(ename,sal) values('LAKSHMI',2000);

select * from XX_EMP1

note: variable assignement for sequences in Pl/sql blocks


Variable name := sequence.nextval

ex:

drop TRIGGER tr14;


/
create or replace trigger tr14

before insert on XX_EMP1

for each row

Begin
:new.empno :=S5.nextval;

end;
/

insert into XX_EMP1(ename,sal) values('DEVA',3000);

select * from XX_EMP1;

Execution order in Tiggers


==========================
Before statemnt level
Before row level
After row level
After staement level

calling procedures in Triggers


===============================

using call staement we are calling procedures into Triggers

create table totalsal( sal number(10);


/

Create or replace procedure p20

is

V_tot number(10);

Begin

delete from totalsal;

select sum(sal) into V_tot from emp;


insert into totalsal(V_tot);

end;
/

create or replace trigger t15

after insert or update or delete on emp

call p20

29025

update emp set sal =sal-200;

select * from totalsal;

Mutating error or mutating table or mutating trigger


====================================================

IF a row level trigger based on a table the trigger body cannot read the data from
same table

and we cannont perfor dml operations on same table.if we trying this oracle server
voilets on error

ORA-04091 table is Mutating

But staement level trigger does not view these type of error .
To overcome mutating problem oracle intraduced insted of triggers.

ex:

create or replace trigger tr15

after delete on xx_emp2

for each row

declare

a number(10);

Begin

select count(*) into a from emp;

dbms_output.put_line(a);
end;
/
there are 12 types of triggers supported by oracle

row level ,staement lvele after, before insert, update,delete

Row level
--------
before insert
before update
before delete
after insert
after update
after delete

staement lvel
--------------
before insert
before update
before delete
after insert
after update
after delete

along with oracle support insted of triggers and system triggers.

system Triggers
================

we can also create triggers on schema level.these triggers also called DDL triggers
because here we are using ddl commands.

synatx:

create or repalce trigger trigger name

before/after create/alter/drop/truncate/rename on username.schema


decalre
Begin
-----

---

end;

ex: create a trigger on apps.schema not drop XX_EMP4 ?

create or replace trigger tr16

before drop on apps.schema

Begin

if ora_dict_obj_type='TABLE' and ora_dict_obj_name='XX_EMP4' THEN

Raise_application_error(-20123,'we cannot drop the table');


end if;
end;
/

drop table XX_EMP4;

create table XX_EMP4 as select * from XX_EMP3;

- we can also enable or disable triggers in table .

also enable ,disbale single trigger

syntax
------

single trigger
===============
alter trigger trigger name enable/disable

all Triggers
===========
alter table table name enable/disable all trigggers

all triggers stored in following TABLE

desc user_triggers

select * from user_triggers where trigger_name='TR10';

Packages
=========

package is a database object which contatins collection of


Procedures,function,variables,cursors triggers and types.

Package does not have a parameters , cannot be invoked and can not be
nested.package having 2 parts

1. package specification
2. package body

Package specification we are defining public member data where as in package body
we are defining pravite member data.

i.e we are declaring sub programs ,global variables ,cursors in package


specification and we are implemening procedures and
functions in package body.

Advantages of packages:
========================
1. we can group the objects which are related for siniler business functionality.

2. If we call the package the entire package will come into buffer. when we call
the next procedure for the packge it will pick from the

buffer it will reduce the network traffic

3 modularity(function,procedures overloading)

synatx:

package specification
-----------------------

Create or replace package package name

IS/AS

global variables,

procedure decalaration

function decalaration

Cursor declararion

type declaration

end;

package body
-------------

create or replace package body package name

IS/AS

procedure implementation

function implementation

end;

Execution
---------

package name.subprogram name( actual parameters)

ex:

create or replace Package TEST_PKG


is

procedure TEST_PROC;

procedure TEST_PROC1;

end;

create or replace Package body TEST_PKG

is
procedure TEST_PROC
is

begin

dbms_output.put_line('procedure1');

end TEST_PROC ;

procedure TEST_PROC1
is

begin

dbms_output.put_line('procedure2');

end TEST_PROC1;

end;
/

Gobal variable
-------------

Create or replace package XXRR_GLOBAL_PKG

is

g number(10) :=300;

procedure test_p1;

function test_f1 ( a number) return number;

end;
/

Create or replace package body XXRR_GLOBAL_PKG

is

procedure test_p1
is

z number(10);

Begin

z := g*2;

dbms_output.put_line(z);

end;

function test_f1 ( a number) return number;

is

Begin

return g*a;

end;

END;
/

select XXRR_GLOBAL_PKG.test_f1(10) from dual;

exec XXRR_GLOBAL_PKG.test_p1;

ex 3:

create or replace Package XX_EMP_DETAILS

IS

procedure p1(p_deptno number);

function F1 (p_deptno number) return number;

end XX_EMP_DETAILS;
/

create or replace Package body XX_EMP_DETAILS

IS

procedure p1(p_deptno number)

IS

cursor C1 is select * from emp where deptno=p_deptno;

i emp%rowtype;

begin
open c1;

loop

Fetch c1 into i;

exit When c1%notfound ;

dbms_output.put_line(i.ename ||' '||i.empno|| ' '|| i.sal ||' '|| i.DEPTNO );

End loop;
close c1;
End P1;

function F1 (p_deptno number) return number

is

Tota_sal Number(10);

Begin

select sum(sal+ nvl(comm,0)) into Tota_sal from emp where deptno=p_DEPTNO;

return Tota_sal;

end F1;

end XX_EMP_DETAILS;
/

exec XX_EMP_DETAILS.p1(10);

select XX_EMP_DETAILS.F1(10) from dual;

overloading subprograms
========================
overloading refers to same name is use to diffent purposes . Pl/sql also support
overloading subprograms
through packages.

ex:

create or replace package TEST_OVERLOADING

is

procedure p1 (p_sal number, p_comm number);

procedure p1 (p_sal number, p_TAX number);

end TEST_OVERLOADING;
/
create or replace package body TEST_OVERLOADING

is

procedure p1 (p_sal number, p_comm number)

IS

TOT Number(10);

Begin

TOT :=P_SAL+P_COMM;

dbms_output.put_line(TOT);

end ;

procedure p1 (p_sal number, p_TAX number)

IS
TAX Number(10);

Begin

TAX :=P_SAL-P_TAX;

dbms_output.put_line(TAX);

END ;

end TEST_OVERLOADING;

exec TEST_OVERLOADING.p1(P_SAL=>5000,p_comm =>1000);

exec TEST_OVERLOADING.p1(P_SAL=>5000,p_tax =>1000);

note: If overloading programs having same number of parameters and same data types
those procedures executed through

Named notatiotion.

ex2:

create or replace package TEST_OVERLOADING1

is

procedure p1 (a number);
procedure p1 (b varchar2);

end TEST_OVERLOADING1;
/

create or replace package body TEST_OVERLOADING1

is

procedure p1 (a number)
is
Begin

dbms_output.put_line(a);

end;

procedure p1 (b varchar2)

is
Begin

dbms_output.put_line(b);

end;

end TEST_OVERLOADING1;
/

exec TEST_OVERLOADING1.p1(5000);

exec TEST_OVERLOADING1.p1('RAJESH');

Forward declaration
====================
wheanever we are caling procedure with in other procedure ,wheanever we are using
forward declararion

i .e wheanever we are calling local procedures into global procedures we must


implement local procedures otherwise use
an forward declaration in package body.

ex

Create or replace package test_forward

is
procedure p1;
End;

/
Create or replace package body test_forward

is

procedure p2;

procedure p1
is
Begin
p2;
end p1;

procedure p2
is

Begin

dbms_output.put_line('local procedure');

end p2;

End;
/

exec

exec test_forward.p1;

ex:

create table XXTEST_BACKUP(EMPNO Number(10),ENAME VARCHAR2(30),SAL number(10));


/

create or replace package XX_FORWARD

is

procedure DETATILS_emp;

end XX_FORWARD;
/

create or replace package body XX_FORWARD

is

procedure INSERT_emp;

procedure delete_emp;

procedure DETATILS_emp
IS

cursor c1 is select * from XXTEST_BACKUP;

i XXTEST_BACKUP%rowtype;
Begin
insert_emp;
open c1;
Loop
fetch c1 into i;

Exit when C1%notfound;

dbms_output.put_line(i.EMPNO||' '||i.ENAME||' '||i.sal);

END LOOP;

Close c1;

end DETATILS_emp;

procedure insert_emp
is

Begin

delete_emp;
insert into XXTEST_BACKUP values(1,'RAJESH',5000);
insert into XXTEST_BACKUP values(2,'RAKESH',3000);
insert into XXTEST_BACKUP values(3,'LAKSHMI',2000);
insert into XXTEST_BACKUP values(4,'RAM',1000);
insert into XXTEST_BACKUP values(5,'ABC',3000);

commit;
End insert_emp;

procedure delete_emp

is
begin

delete XXTEST_BACKUP;

commit;
end delete_emp;

end XX_FORWARD;
/

exec XX_FORWARD.DETATILS_emp;

Advanced collections
======================

we can aslo create user defined data types in oracle though type keyword.

genarally we are creating types in 2 steps process.

1. we are creating user defined types using appropriate synatx.


2. creating the variable

1. pl/sql record
2. index by table/pl/sql table
3. nested table
4. varry
5. ref curors

advanced collection:

2. index by table/pl/sql table


3. nested table
4. varry

1. pl/sql record
===============

This is an user define type used to store different data items into single
unit.This is also call as record type variable.

syntax:

step1: type type name is record ( attribute1 datatype, attribute2


datatype ........................................ );

step2: Variable name type name:

ex:

create or replace package XX_RECORD_OKG

IS

procedure p1;

type t1 is record( a number(10),b varchar2(30),c number(10), d date);

end XX_RECORD_OKG;
/

create or replace package body XX_RECORD_OKG

IS

procedure p1

is

V_t t1;

Begin

select empno,ename,sal,hiredate into V_t from emp where empno=7499;

dbms_output.put_line(V_t.a ||' '||V_t.b||' '||V_t.c|| ' '||V_t.d);

end;

end XX_RECORD_OKG
/
set serveroutput on;

exec XX_RECORD_OKG.p1;

ex 2:

reate or replace package XX_RECORD_OKG1

IS

procedure p1;

type t1 is record( a number(10),b varchar2(30),c number(10), d date);

procedure p2;

end XX_RECORD_OKG1;
/

create or replace package body XX_RECORD_OKG1

IS

procedure p1

is

type t1 is record( a number(10),b varchar2(30),c number(10), d date);

V_t t1;

Begin

select empno,ename,sal,hiredate into V_t from emp where empno=7499;

dbms_output.put_line(V_t.a ||' '||V_t.b||' '||V_t.c|| ' '||V_t.d);

end;

procedure p2

is

type t1 is record( a number(10),b varchar2(30));

V_t t1;

Begin
select empno,ename into V_t from emp where empno=7499;

dbms_output.put_line(V_t.a ||' '||V_t.b);


--dbms_output.put_line(V_t.a ||' '||V_t.b||' '||V_t.c|| ' '||V_t.d);

end;

end XX_RECORD_OKG1;
/

set serveroutput on;

exec XX_RECORD_OKG1.p2;

Index by tables or pl/sql tables


===============================

These are user defined data types used to store number of items in a single
unit.there are un constrant tables and there
tables are improve the performence of the application.

i.e these table are stored in SGA(system global area) .RAM memory area

index by tables having 2 parts

1.data part: data part stores in actul data

2. index part: stores in index values

Index part contatins either binary- integer or pl/sql - integer

This is user defined data type so we can creating 2 steps process.

syntax:
============

step1 : type type nmae is table of datatype(size) index by binary_integer;

step 2: variable name type name;

ex :

Declare

type t1 is table of Number(10) index by binary_integer;

V_t t1;

Begin

v_t(1) := 10;
v_t(2) := 20;
v_t(3) := 30;
v_t(4) := 40;
v_t(5) := 50;
v_t(6) := 60;

dbms_output.put_line(v_t(3));
dbms_output.put_line(v_t.first);
dbms_output.put_line(v_t.last);
dbms_output.put_line(v_t.prior(3));
dbms_output.put_line(v_t.next(4));
dbms_output.put_line(v_t.count);

v_t.delete;

-- dbms_output.put_line(v_t(3));
dbms_output.put_line(v_t.first);
dbms_output.put_line(v_t.last);
dbms_output.put_line(v_t.prior(3));
dbms_output.put_line(v_t.next(4));
dbms_output.put_line(v_t.count);

end;
/

Collection methods
--------------------
COUNT - Returns the number of elements in a collection.
DELETE - Removes all elements from a collection.
DELETE (n) - Removes element n from an associative array. You cannot delete
individual elements from a VARRAY collection type. .
DELETE (n1, n2) - Removes all elements from n1 to n2 from an associative array.
You cannot delete individual elements from a VARRAY collection type.
EXISTS (n) - Returns TRUE if the specified element exists.
EXTEND - Appends a single NULL element to a collection.
EXTEND (n) - Appends n NULL elements to a collection.
EXTEND (n1, n2) - Appends n1 copies of the n2th element to a collection.
FIRST - Returns the smallest index number in a collection.
LAST - Returns the largest index number in a collection.
LIMIT -Returns the maximum number of elements for a VARRAY, or NULL for nested
tables.
NEXT (n) - Returns the index number of the element immediately following the
specified index.
PRIOR (n) - Returns the index number of the element immediately prior to the
specified index.
TRIM - Removes a single element from the end of a collection. You cannot trim
elements from an associative array collection type.
TRIM (n) - Removes n elements from the end of a collection. You cannot trim
elements from an associative array collection type.

EXMPLE:
Write a pl/sql program using EMP table retrive all employee names from emp
tables and store in index by tables and also
disply content of pl/sql table or index by table:

Declare
type t1 is table of Varchar2(10) index by binary_integer;

v_t t1;

cursor c1 is select ename from emp;

i integer :=0;

Begin

open c1;

loop

fetch c1 into v_t(i);

exit when c1%notfound;

i:=i+1;
dbms_output.put_line(i);
end Loop;

Close c1;

For i in v_t.first..V_t.last

loop

dbms_output.put_line(v_t(i));

end loop;

end;
/

Bull Collect
============

Bulk collect is one of the method of fetching the data from data base.

The sql engin to collect many rows at once and place them in collections. It will
improve the performence.

ex:

Declare

type t1 is table of Varchar2(10) index by binary_integer;

V_t t1;

begin

select ename bulk collect into V_t from emp;

for i in V_t.first .. V_t.last


loop

dbms_output.put_line(V_t(i));

end loop;

end;
/

Return result sets


==================

If we want return bulk amout of data from database server into client application.

we are using following 2 methods

1. index by table or pl/sql table

2. ref cursors

If we want develop result sets we are using functions and also we are
implementing server application and client application.

using index by table


====================

server application
==================

create or replace Package XX_RETURN_RESULT_SETS

IS

type t1 is table of emp%rowtype index by binary_integer;

Function F1 return t1;

end;
/

create or replace Package body XX_RETURN_RESULT_SETS

IS

Function F1 return t1

IS

V_t t1;

begin

select * bulk collect into V_t from emp;


return V_t;

end F1;

end XX_RETURN_RESULT_SETS;
/

Client application
====================

Declare

z XX_RETURN_RESULT_SETS.t1;

begin

z:=XX_RETURN_RESULT_SETS.F1;

For i in z.first..z.last
loop

dbms_output.put_line(z(i).ename ||' '|| z(i).sal|| ' '|| z(i).deptno);

end loop;
end;
/

using returning clauses


=======================
genarally returning clause used along with dml statements.Using returning caluses
we are proceesing one record or bulk of records
also we are using bulk collect clause only.This bulk of data stored in
collections.

syntax:

update tablename set column name= modified value where condition returning
col1,col2 ....bulk collect INTO

Collection variable.

ex: write PL/SQL program using bulk collect returning clause modify salary of the
employee 'CLERK' and stored these values
into pl/sql table and also diply the content of the pl/sal table?

Create or replace procedure p1

IS
Type t1 is table of emp%rowtype Index by binary_integer;

v_t t1;
begin

update emp set sal =sal+sal*0.1 where job='CLERK' returning


empno,ename,job,mgr,hiredate,sal,comm,deptno bulk collect into V_t;

dbms_output.put_line('no of records update'||sql%rowcount);

for i in v_t.first..v_t.last
loop

dbms_output.put_line(v_t(i).ename||' '||v_t(i).empno||' '||v_t(i).sal);


end loop;

end;

Ref cursors
===========

Ref cursors are user defined data type used to process multiple records.

Genarally static cursors bound only one select statement at compile time
where as in ref cursors only one active set area bound to number of select
staements dyanamically at runtime.

Genarally static cursor not allowed to pass as parameter to the sub program
(procedure,functions) but ref cursor is a variable we
are passing parameter into the sub programs.

There are 2 types of ref cursors supported by Oracle

1. strong ref cursor

2. weak ref Cursor

strong ref cursor is a refcursor which contains return type where as weak
refcursor not having a return type.

These are user define types we can createing 2 steps process.

syntax:

strong ref cursor


================
step 1: type typename is ref cursor return record type;

step 2: variable name typename

weak ref Cursor


==================

type typename is ref cursor

variable name typename


Note: here we are opening number of select staements though Open for staement

ex:
Declare

type t1 is ref cursor;

V_t t1;

I emp%rowtype;

begin

open V_t for select * from emp where sal>2000;

loop
fetch V_t into i;

exit when V_t%notfound;

dbms_output.put_line(i.ename ||' '|| i.sal);

end loop;

open V_t for select * from emp where sal<2000;

loop
fetch V_t into i;

exit when V_t%notfound;

dbms_output.put_line(i.ename ||' '|| i.sal);

end loop;

close V_t;
end;
/

ex:

Declare

type t1 is ref cursor;

V_t t1;

I emp%rowtype;

begin

open V_t for select * from emp where sal>2000;


dbms_output.put_line('salary grater than 2000');
loop
fetch V_t into i;

exit when V_t%notfound;

dbms_output.put_line(i.ename ||' '|| i.sal);

end loop;
open V_t for select * from emp where deptno=10;
dbms_output.put_line('deptno 10 employee');
loop
fetch V_t into i;

exit when V_t%notfound;

dbms_output.put_line(i.ename ||' '|| i.sal);

end loop;

close V_t;

open V_t for select * from emp where deptno=20;


dbms_output.put_line('deptno 20 employee');
loop
fetch V_t into i;

exit when V_t%notfound;

dbms_output.put_line(i.ename ||' '|| i.sal);

end loop;

close V_t;

end;

ex: write pl/sql program using refcursor wheanever enter 10th department display
the details from emp table and also whenever
user enter 20th department diaplay the details from dept table:

Declare

type t1 is ref cursor;


v_t t1;

i emp%rowtype;

j dept%rowtype;

v_deptno number(10) :=&enterdeptno;

begin

If V_deptno=10 Then
open V_t for select * from emp where deptno=10;
loop
Fetch V_t into i;

exit when V_t%notfound;

dbms_output.put_line(i.ename|| ' '||i.sal||' ' || i.deptno);


end loop;

close v_t;

elsif V_deptno=20 Then

open V_t for select * from dept where deptno=20;


loop
Fetch V_t into j;

exit when V_t%notfound;

dbms_output.put_line(j.deptno|| ' '||j.dname||' ' || j.loc);


end loop;
close v_t;
end if;
end;
/

Using subprogram Parameter


===========================

Create or replace package XX_REFCURSOR_TEST


IS
type t1 is ref cursor return EMP%rowtype;

type t2 is ref cursor return DEPT%rowtype;

procedure p1(v_t1 out t1);

procedure p2(v_t2 out t2);

end;
/

Create or replace package body XX_REFCURSOR_TEST

IS

procedure p1(v_t1 out t1)


IS
begin

open v_t1 for select * from emp;

end;

procedure p2(v_t2 out t2)


IS
begin

open v_t2 for select * from DEPT;

end;

end;
/

set serveroutput on;

set line 100;

variable a refcursor;

variable b refcursor;

exec XX_REFCURSOR_TEST.p1(:a);

exec XX_REFCURSOR_TEST.p2(:b);

print a b ;

print a ;

print b ;

note:

Oracle 9i introduced sys_refcursor type in place of weak ref cursor

synatax:

variable name sys_refcursor;

EX

Declare

v_t sys_refcursor;

I emp%rowtype;

begin

open V_t for select * from emp where sal>2000;


dbms_output.put_line('slary graterthan 200');
loop
fetch V_t into i;

exit when V_t%notfound;

dbms_output.put_line(i.ename ||' '|| i.sal);

end loop;

open V_t for select * from emp where sal<2000;

dbms_output.put_line('slary lesstahn 2000');


loop
fetch V_t into i;

exit when V_t%notfound;

dbms_output.put_line(i.ename ||' '|| i.sal);

end loop;

close V_t;
end;
/

Nested tables and Varrays


==========================

These are user defined types to store multiple items in single unit.Genarally index
by tables not store in database

to overcome This problem oracle intraduced nested tables and vaarys.though the sql
we are storing nested tables ,varrys INTO
databse.

Before we are storing data into Varrays,nested tables we must intialize though
constractor.constractor name is same as type name.

Nested table is an un constrant table same like Index by table but not allowed to
negative index's and it will start with '1'

synatax:

type typename is table of datatype(size);

variablename type name := type name ();

example:(index by table)

declare

type t1 is table of NUmber(10) index by binary_integer;

V_t t1;
begin
V_t(500) :=80;

dbms_output.put_line(v_t(500));

end;
/

output : 80

note: whenever we are using index by tables we are not required to reslove the
memory explicitly because based ON

specific key value and based on value field memory automatically allocated.

nested table
==============

declare

type t1 is table of NUmber(10);

V_t t1 :=t1();
begin

V_t(500) :=80;

dbms_output.put_line(v_t(500));

end;

error: ORA-06533: Subscript beyond count

solution:

declare
type t1 is table of NUmber(10);

V_t t1 :=t1();
begin
v_t.extend(500);
V_t(500) :=80;

dbms_output.put_line(v_t(500));

end;

ex 2:

declare

type t1 is table of NUmber(10);

V_t t1 :=t1();
begin
v_t.extend(5)
V_t(1) :=10;
V_t(2) :=20;
V_t(3) :=30;

dbms_output.put_line(v_t(1));

end;

note: without using "extend " collection method also we can store the data
directly into nested tables. in this we must
specify the atual data with in constractor itself.

declare

type t1 is table of number(10);

V_t t1 :=t1(10,20,30,40,50,60,70);
begin
dbms_output.put_line(v_t.first);
dbms_output.put_line(v_t.last);

for i in v_t.first..v_t.last
loop
dbms_output.put_line(v_t(i));
end loop;
end;
/

Declare

type t1 is table of number(10);

V_t1 t1;
v_t2 t1 :=t1()
begin

if V_t1 is null Then


dbms_output.put_line( 'v_t1 is null');
else
dbms_output.put_line( 'v_t1 is not null');

end if

if V_t2 is null Then


dbms_output.put_line( 'v_t2 is null');
else
dbms_output.put_line( 'v_t2 is not null');

end if

end;

clarification;
v_t1 t1 -- null

v_t1 t1 :=t1() /* |-|-|-|-| */

declare

type t1 is table of NUmber(10) index by binary_integer;

V_t t1 :=t1();
begin
v_t.extend;
V_t(1) :=10;

dbms_output.put_line(v_t(1);

end;

/* |10|-|-|-| */

declare

type t1 is table of NUmber(10);

V_t t1 :=t1(10,20,30,40,50);
begin
dbms_output.put_line(v_t.first);
dbms_output.put_line(v_t.last);
dbms_output.put_line(v_t.prior(3));
dbms_output.put_line(v_t.next(2));
dbms_output.put_line(v_t.count);

V_t.extend(3);
v_t(6) :=60;
v_t(7) :=70;
v_t(8) :=80;

for i in v_t.first..v_t.last
loop
dbms_output.put_line(v_t(i));
end loop;

v_t.delete;

dbms_output.put_line(v_t.count);
end;

/
trim: delete indexes last indexe onwards
delete(index): delete any element in any position with in nested table.

declare

type t1 is table of NUmber(10) index by binary_integer;

V_t t1 :=t1(10,20,30,40,50);
begin
dbms_output.put_line(v_t.count);
v_.t trim;

dbms_output.put_line(v_t.count);

--v_t.delete(2);
for i in v_t.first..v_t.last
loop
dbms_output.put_line(v_t(i);
end loop;

v_t.delete

dbms_output.put_line(v_t.count);
end;

VARRAYS are user defined types used to store data items into single unit. these are
not un constrant tables.These types behavious like

arrays in normal language. It is bounded array which used to store 2 GB data.

Before we are storing data into Varrays,nested tables we must intialize though
constractor.constractor name is same as type name.

syntax:
type typename is varray(size) of datatype(size);

variable name type name := type name()

example:

Declare

type t1 is varray(10) of varchar2(10);

V_t t1 :=t1('a','b','c','d' );

flag boolean;

begin

--- V_t.extend(10);

dbms_output.put_line (V_t.limit);
dbms_output.put_line (V_t.count);
dbms_output.put_line (V_t.first);
dbms_output.put_line (V_t.last);
dbms_output.put_line (V_t.prior(2));
dbms_output.put_line (V_t.next(3));

for i in v_t.first..v_t.last

loop
dbms_output.put_line (V_t(i));

End loop;

Flag :=v_t.exists(3);

--dbms_output.put_line ( Flag);

If flag=true then
dbms_output.put_line ('index 3 having element'||' '||v_t(3));
end if;

v_t.extend;

v_t(5):='e';

dbms_output.put_line (v_t(5));

Flag :=v_t.exists(5);
if flag=true then

dbms_output.put_line ('index 5 having element'||' '||v_t(5));

else

dbms_output.put_line ('index 5 not having element');

end if;

v_t.extend(2,3);

for i in v_t.first..v_t.last

loop
dbms_output.put_line (V_t(i));

End loop;

v_t.delete;

dbms_output.put_line (V_t.count);
end;
/

note: vaary cannot delete particlar elements or range of indexes by using 'delete'
collection method
because vaarys is not sparse.vaarys does not have any gaps but we can delete all
elements by using delete collection method.
declare

type t1 is varray(10) of varchar2(10);


v_t t1:=t1();

begin

select ename bulk collect into v_t from emp where rownum<=10 ;

for i in v_t.first..v_t.last
loop
dbms_output.put_line(v_t(i));
end loop;

end;

bulk bind
==========

wheanever we are submittimg pl/sql into the server ,sql,pl/sql statements are
executed saparetly.i.e sql statements

are executed in sql engine,pl/sql statements are executed in pl/sql engine.this


type of execution called context swithing.

whenever large amount of data is there oracle server degrade the performence
because of context swithing.To avoid

context swithing oracle intraduced Bulk binds.

i. e we are executing all sql staements at a time using collections in this case we
are using either varrays or nested tables.

Genarally bulk binds used to improve the performence so insted of loops better to
use for all statements.

synatx:

for all variable name in lower bound .. upper bound dml statements.

Declare

type t1 is varray(10) of number(10);

v_t t1 := t1(10,20);

begin

forall i in v_t.first..v_t.last

delete from t40 where deptno=v_t(i);

end;
/
ex 2:

Declare

type t1 is varray(10) of number(10);

v_t t1 := t1(10,20,30,40,50,60);

begin

forall i in v_t.first..v_t.last

update t40 set sal= sal+sal* 0.2 where deptno=v_t(i);

end;
/
/

You might also like