You are on page 1of 9

Cursors:

It is an Temporary buffer used to hold the


transactional data for manipulation purpose.
It is not stored in database.
It is not Re-usable.
It is valid in Pl/sql Block only.
It is created in the Logical memory only.
2 Types :
1. Implicit cursors: Automatically created by oracle
ns are performed by
user.

whenever " DML" operatio

2. Explicit Cursors: Created by user in Pl/sql Block.


* Used to retrieve multiple rows from multiple
tables into pl/sql
block for manipulation
purpose. It is based on SELECT stmt.
Explicit Cursors : 3 Steps
I. Declaring Cursor
II. Cursor Operations
III. Cursor Attributes
I . Declaring Cursor
Syntax: cursor <cursor name> is <select stmt>;
ex: cursor c1 is select * from emp;
II. Cursor Operations:
i> open <cursor name>;
used to open the cursor.
memory will be alloted to cursor after opening it.
ii>Fetch <cursor name> into < Variables >;
Used to retrieve data from cursor to pl/sql
At a time it can retrieve only one row into
y Fetch will be placed in loop .

variables.
variables. Generall

iii> close <cursor name>;


used to close the cursor.
memory alloted will be Deallocated .
III. Cursor Attributes
Gives the status of cursor
<cursor name>%<attribute>
a> %isopen --- Returns True / False
Returns True if cursor is opened successfully
b> %found --- Returns True / False
Returns True if Fetch statement sucessfully
into pl/sql variables.
c> %notfound --- Returns True / False
Returns True if Fetch statement fails to retrieve
l variables.
d> %rowcount --- Returns Number
Returns the No.of rows sucessfully retrieved

retrieves the data

the data into Pl/sq

from cursor so far.

Initially it holds 0.
After every sucessful "Fetch" it is incremented
by 1.
--------------------------------------------------------------Using Explicit Cursors:

* Pl/sql Block calculates new commission for ALL


t Cursors:

employees using Explici

declare
cursor c1 is select empno,ename,comm from emp
order by deptno;
veno emp.empno%type;
vname emp.ename%type;
vcomm emp.comm%type;
begin
open c1;
IF c1%isopen THEN
dbms_output.put_line
(' Employ New Commission Report ');
loop
fetch c1 into veno,vname,vcomm;
exit when c1%notfound;
if vcomm is null then
vcomm := 3000;
elsif vcomm = 0 then
vcomm := 2500;
else
vcomm := vcomm + vcomm * .25;
end if;
update emp set comm = vcomm
where empno = veno;
dbms_output.put_line(c1%rowcount||' '||veno
||' '||vname||' '||vcomm);
end loop;
dbms_output.put_line(c1%rowcount ||' Employees are updated with new commission
');
close c1;
commit;
ELSE
dbms_output.put_line(' Unable to open cursor... ');
END IF;
end;
--------------------------------------------------------------* Provides serial no. for employ code :
create sequence s11 increment by 1
start with 7001;
update emp set empno = s11.nextval;
-------------------------------------------------------------student -- roll,name,class,m1,m2,m3,m4,m5,m6
--------------------------------------------------------------* Pl/Sql block calculates Total marks and Average
marks of all students & Gi
ve Average marks of
class:
declare
cursor c2 is select roll,name,m1,m2,m3,m4,m5,m6 from student where class = 10;
i c2%rowtype; -- cursor record type declaration
-- i student%rowtype;
totmarks number(6);
avgmarks number(5,2);
classtot number(12) := 0;
classavg number(7,2);
begin
open c2;
dbms_output.put_line(' Student Report ');
loop
fetch c2 into i;

exit when c2%notfound;


totmarks := i.m1 + i.m2 + i.m3 + i.m4 + i.m5 +
avgmarks := totmarks / 6;
classtot := classtot + totmarks;
dbms_output.put_line(i.roll||' '||i.name
||' '||totmarks||' '||avgmarks);
end loop;
classavg := classtot / c2%rowcount;
dbms_output.put_line('Average marks of Class is :
'||classavg);
close c2;
end;
--------------------------------------------------------------Exercise:
create " Item_Master " Table and insert the rows.
Itno -- 101
Name -- RICE
UOM - Kgs (Unit of Measurement - Pcs,Ltr,Mtr,Kgs)
Class - (A,B,C) -- C
Description -- Export quality
Rate -- 30
ROL ( Re order Level ) -- 100
ROQ ( Re order Quantity ) -- 500
QOH ( Quantity on hand ) -- 60

i.m6;

* Write a pl/sql program to print the item details


with total value ( qoh
* rate ) and also print total
value of entire stock. -- 101 rice 1800
* Write a pl/sql program to print the items to be
Re-ordered. ( if qo
h <= rol ).
--------------------------------------------------------------* Pl/SQL Block using Cursor with operations:
declare
cursor c2 is select * from dept;
i c2%rowtype;
begin
open c2;
loop
fetch c2 into i;
-- exit when c2%notfound;
if c2%found then
Dbms_output.put_line(c2%rowcount||' '||i.deptno
||' '||i.dname||' '||i.loc);
else
exit;
end if;
end loop;
close c2;
end;
Cursor For Loop:
used to perform cursor operations automatically.
Improves performance.
Syntax:
For < variable > in <cursor name> loop
< Exec stmts >;
End loop;
Advantage: No need to
1. open cursor
2. fetch rows
3. check for end of rows

4. close cursor
5. declare variables
--------------------------------------------------------------- * Pl/SQL Block
using Cursor For Loop:
declare
cursor c2 is select * from dept;
begin
for i in c2 loop
dbms_output.put_line(c2%rowcount||' '||i.deptno
||' '||i.dname||' '||i.loc);
end loop;
-- close cursor
end;
for i in c2 loop ---> declares i variable
open cursor
fetch 1 row into i
check for end of rows -------------------------------------------------------------Ex: Different Cursor Declarations
Cursor with Equi join:
cursor ecur is select empno, ename, sal, job,
emp.deptno, dname, loc
from emp, dept
where emp.deptno = dept.deptno;
Cursor with arthematic expressions :
declare
cursor epays is select empno ecode, sal basic,
round(sal *.25) da, round(sal * .35) hra,
round(sal * .15) pf,
round(sal + sal * .25 + sal * .35 - sal * .15) gross
from emp where sal >= 7000;
tg number(15) := 0;
tp number(12) := 0;
begin
dbms_output.put_line(' Employees Pay Report ');
dbms_output.put_line(' Ecode
Basic
Da
Hra
Pf
for k in epays loop -- k epays%rowtype
dbms_output.put_line(k.ecode||' '||k.basic
||' '||k.da||' '||k.hra||' '||k.pf||' '||k.gross);
tg := tg + k.gross;
tp := tp + k.pf;
end loop;
dbms_output.put_line(' Total Pf is : '||tp);
dbms_output.put_line(' Total Gross pay is : '||tg);
end;
Cursor Using Scalar Query:
declare
cursor c3 is select empno, ename, job, sal,
(select min(sal) from emp where job = E.job)
Lopay,
(select max(sal) from emp where job = E.job)
Hipay
from emp E order by job;
begin
dbms_output.put_line(' Job wise Salary Limits ');
dbms_output.put_line(' Empno
Emp name
Job
Salary
');
for k in c3 loop
dbms_output.put_line(k.empno||' '||k.ename
||' '||k.job||' '||k.sal||' '||k.lopay||' '||k.hipay);
end loop;

Gross ');

Lopay

Hipay

end;
--------------------------------------------------------------* Pl/Sql Block calculating Bonus for all employees:
declare
cursor c1 is select empno, ename,
sal + nvl(comm,0) net, job from emp order by sal;
i c1%rowtype;
bonus number(12,2);
totbonus number(20) := 0;
begin
dbms_output.put_line(' Employee Bonus Report ');
dbms_output.put_line(' Sno Empno Emp Name
Job Bonus ');
for i in c1 loop
if i.job = 'CLERK' then
bonus := round(i.net * 1.25);
elsif i.job = 'SALESMAN' then
bonus := round(i.net * 1.35);
elsif i.job = 'MANAGER' then
bonus := round(i.net * 1.65);
else
bonus := round(i.net * 1.75);
end if;
totbonus := totbonus + bonus;
dbms_output.put_line(c1%rowcount||' '||
i.empno||' '||i.ename||' '||i.job||' '||bonus);
/* Calculate bonus for first 10 lowest paid
employees only */
-- exit when (c1%rowcount >= 10);
/* total bonus upto 200000 only
IF totbonus > 200000 THEN
exit;
END IF; */
end loop;
dbms_output.put_line(' Total bonus is
end;

'||totbonus);

** exit when (c1%rowcount >= 10 or


totbonus >= 200000);
--------------------------------------------------------------Exercise:
Write a Pl/sql program to print 2 Tables content
independently with prope
r Titles as below :
Department Information
Dept id
Dept Name
Location
Employee Information
Empno Emp Name Salary .......
--------------------------------------------------------------* Cursor With Parameters: (8.0)
Used to accept the input dynamically while
Supports to define generalized cursors.
Maximum 32 parameters can be passed to Cursor.
* Used to pass the arguments from other s/w tools.
Dedicated cursor
cursor c1 is select * from emp
where deptno = 10;
declare

opening the cursor.

-- Dynamic cursor
cursor c1(dno number) is select * from emp
where deptno = dno;
begin
open c1(10);
------------------------------close c1;
open c1(30);
~~~~~~~~~~~
~~~~~~~~~~~
close c1;
end;
-----------------------------------------------------------* Pl/Sql block calculates increment for a particular
dept employees. ( usi
ng Cursor Parameters ):
declare
cursor c1(dno number) is select * from emp
where deptno = dno;
i c1%rowtype;
incr number(16);
net number(16,2);
expr number(2);
begin
open c1(&dept);
dbms_output.put_line(' Employ Increment
Report ');
loop
fetch c1 into i;
exit when c1%notfound;
net := i.sal + nvl(i.comm,0);
expr :=
round(months_between(sysdate,i.hiredate)/12);
if expr <= 2 then
incr := net *.25;
elsif expr < 5 then
incr := net * .45;
else
incr := net * .65;
end if;
update emp set sal = sal + incr
where empno = i.empno;
dbms_output.put_line(i.empno||' '||i.ename
||' '||i.job||' '||i.deptno||' '||expr||' '||incr);
end loop;
close c1;
-- commit;
-- Re-opening cursor in For loop
dbms_output.put_line ( 'Employ Details are :' );
for k in c1(&deptid) loop
dbms_output.put_line(k.empno||' '||k.ename
||' '||k.job||' '||k.deptno||' '||k.hiredate);
end loop;
end;
enter value for dept: 10
enter value for deptid: 30
Ex 2:

cursor c2(dno number, vjob varchar2) is


select * from emp where deptno = dno
and job = vjob;
* open c2(30,'CLERK');
* for i in c2(20,'SALESMAN') loop
Ex 3:
cursor c3(vcourse varchar2, vtime varchar2) is
select * from student where course = vcourse
and timing = vtime;
* open c3('Oracle9i', '10 am');
* for k in c3('Oracle9i', '4.30 pm') loop
cursor c4 is select * from student
where course = '&course'; -- dynamic cursor
* It is valid in oracle sql environment only. & is Not supported while using P
l/sql programs in other s/w tools .
* Cursor Parameters are used to pass values from other Application s/w tools li
ke Java , .Net, Developer 6i, ERP's , ..... etc
* Explicit cursors are used to retrieve Huge loads
of data from multiple ta
bles into Logical memory for processing purpose .
-----------------------------------------------------------* List the employees who r working in New york
city .
select empno, ename, sal, job from emp
where deptno = (select deptno from dept
where loc = 'NEW YORK');
* Printing same results thru pl/sql block .
declare
cursor ecur(city varchar2) is select
empno, ename, sa
l, job from emp
where deptno IN (select deptno from dept
where loc = city);
begin
for k in ecur('&deptloc') loop
dbms_output.put_line(k.empno ||' '||
k.ename||' '||k.sal||' '||k.job);
end loop;
end;
-----------------------------------------------------------* pl/sql block with 2 cursors.
declare
cursor c11 is select empno,ename,sal from emp
order by sal;
cursor c12 is select empno,ename,sal from emp
order by sal desc;
begin
dbms_output.put_line(' Employ details with salary
in Ascending order ');
for k in c11 loop
dbms_output.put_line(k.empno||' '||k.ename
||' '||k.sal);
end loop;
dbms_output.put_line(' Employ details with salary
in Descending order ');
for h in c12 loop
dbms_output.put_line(h.empno||' '||h.ename
||'
'||h.sal);
end loop;

end;
/
declare
cursor c1 is select * from student;
cursor c2(vroll number) is select * from fee_instalments where roll = vroll;
begin
for i in c1 loop
student
fee_instalments
for k in c2(i.roll) loop
roll
roll
-----sname
amt
------course
dop
end loop;
end loop;
end;
101 Sriram Oracle
1 500
-----2 1000 -----3 600
-------------------------------------------------------------------Implicit Cursors:
- Automatically defined by oracle whenever
"DML" operations are performed
by user.
- It has a fixed name " SQL ".
* - It gives the status of "DML" stmts in pl/sql

Block

- It will not support cursor operations.


- It supports %found,%notfound,%rowcount
%found returns TRUE if DML is success.
%notfound returns TRUE if DML is failure.
%rowcount returns no.of rows manipulated by
pen is not valid.

attributes.
DML statement.

>update emp set sal = sal + 2000


where empno = 790;

%iso

begin
update emp set sal = sal + 2000
where empno = 790;
dbms_output.put_line(' Employ Updated ');
end;
In above program we r unable to find DML stmt
Using Implicit cursor it is possible to know

Status.
status.

Using Implicit cursors:


* pl/sql block Trapping Update stmt status.
declare
vdept number(2) := &dept;
begin
update emp set sal = sal + 1000
where deptno = vdept;
if sql%Notfound then
dbms_output.put_line('Unable to Update rows - No
such dept exists');
else
dbms_output.put_line(sql%rowcount||' Employees are updated sucessfully ');

commit;
end if;
end;
--------------------------------------------------------------* pl/sql block trapping Delete stmt status.
declare
vdept number(2) := &dept;
begin
delete from emp where deptno = vdept;
if sql%rowcount > 3 then
dbms_output.put_line(' Invalid operation - cannot
remove more than 3 employe
es ');
rollback;
else
dbms_output.put_line(sql%rowcount||' Employees are removed');
commit;
end if;
end;
Note: Implicit cursor holds only recently executed
DML statement status but not the previous DML
statement status .
---------------------------------------------------------------