CURSORS
The ‘CURSOR’ is the PL/SQL construct that
allows the user to give a user defined name
to the work area and access the stored
information in it.
Use of cursor:
The major function of a cursor is to
retrieve data, one row at a time
Cursors are used when the user needs to
update records in a row by row manner, in
a table.
The Data that is stored in the Cursor is
Active data set
Cursor Actions
Declare
Open
Fetch
Close
Deallocate
Declare Cursor:
A cursor is declared by defining the
SQL statement that returns a result set
Open:
A Cursor is opened and populated
by executing the SQL statement defined
by the cursor
Fetch:
When the cursor is opened, rows
can be fetched from the cursor one by
one or in a block to perform data
manipulation
Contd.,
Close:
After data manipulation, close the
cursor explicitly.
Deallocate:
Finally, delete the cursor
definition and release all the system
resources associated with the cursor.
Types
Implicit
Explicit
Implicit cursors are automatically created by
Oracle whenever an SQL statement is
executed
A Cursor which is defined by the user in a
PL/SQL block, for data processing is known
as an Explicit Cursor.
Attributes of Implicit Cursor
%FOUND
if DML statements like INSERT, DELETE and
UPDATE affect at least one row or more rows, then
it will return TRUE else it returns FALSE
%NOTFOUND
if DML statements like INSERT, DELETE and
UPDATE does not affect at least one row or more
rows, then it returns TRUE else FALSE
Contd.,
%ISOPEN
It always returns FALSE for implicit
cursors, because the SQL cursor is
automatically closed after executing its
associated SQL statements.
%ROWCOUNT
It returns the number of rows affected
by DML statements like INSERT, DELETE, and
UPDATE or returned by a SELECT INTO
statement.
Example
PL/SQL procedure
DECLARE
total_rows number(2);
BEGIN
UPDATE customers SET salary = salary + 5000;
IF sql%notfound THEN
dbms_output.put_line('no customers updated');
ELSIF sql%found THEN
total_rows := sql%rowcount;
dbms_output.put_line( total_rows || ' customers
updated ');
END IF;
END;
/
Output
6 customers updated
PL/SQL procedure successfully completed
select * from customers;
Updated table
How to declare?
An explicit cursor is defined in the
declaration section of the PL/SQL Block
General Syntax:
CURSOR cursor_name IS select_statement;
cursor_name – A suitable name for the
cursor.
select_statement – A select query which
returns multiple rows
How to use Explicit Cursor?
1. DECLARE the cursor in the Declaration
section to initialize memory
2. OPEN the cursor in the Execution
Section to allocate memory
3. FETCH the data from the cursor into
PL/SQL variables or records in the
Execution Section to retrieve data
4. CLOSE the cursor in the Execution
Section before the end of PL/SQL
Block to release the allocated memory
General Syntax
DECLARE variables;
records;
create a cursor;
BEGIN OPEN cursor;
FETCH cursor;
process the records;
CLOSE cursor;
END;
Declare the Cursor
CURSOR name IS SELECT statement;
CURSOR cust_cur is SELECT * FROM CUSTOMERS;
OPEN CURSOR:
SYNTAX: OPEN cursorname;
Example: OPEN cust_cur;
Fetch cursor
FETCH cursor_name INTO variable_list;
Example:
FETCH cust_cur into c_id, c_name, c_addr;
CLOSE cursor
CLOSE cursorname;
Example: CLOSE cust_cur;
Example
DECLARE
c_id customers.id%type;
c_name customers.name%type;
c_addr customers.address%type;
CURSOR c_customers is
SELECT id, name, address FROM customers;
BEGIN
OPEN c_customers;
LOOP
FETCH c_customers into c_id, c_name, c_addr;
EXIT WHEN c_customers%notfound;
dbms_output.put_line(c_id || ' ' || c_name || ' ' || c_addr)
;
END LOOP;
CLOSE c_customers;
END;
/
Output
1 Ramesh Allahabad
2 Suresh Kanpur
3 Mahesh Ghaziabad
4 Chandan Noida
5 Alex Paris
6 Sunita Delhi
PL/SQL procedure successfully completed.
DECLARE CURSOR emp_cur IS
SELECT emp_name FROM emp;
employee emp.emp_name%type;
BEGIN OPEN emp_cur;
LOOP
FETCH emp_cur INTO employee;
IF emp_cur%NOTFOUND
THEN EXIT;
END IF;
Dbms_output.put_line(‘Employee
Fetched:‘||employee);
END LOOP;
Dbms_output.put_line(‘Total rows fetched is‘||
emp_cur%R0WCOUNT);
CLOSE emp_cur;
Outpur
Employee Fetched:BBB
Employee Fetched:XXX
Employee Fetched:YYY
Total rows fetched is 3
Example
DECLARE CURSOR student_cursor IS
SELECT sname FROM Student ;
snm Student.sname %type;
BEGIN
OPEN student_cursor;
IF student_cursor%ISOPEN= FALSE
then dbms_output.put_line('Cannot open cursor');
ELSE
LOOP
FETCH student_cursor INTO snm;
IF student_cursor%NOTFOUND then Exit;
END IF;
dbms_ output.put_line('' ||snm);
END LOOP;
END IF;
CLOSE STUDENT_CURSOR;
END;
dbms_output.put_line('Total Records: ' ||
student_cursor%rowcount);
CLOSE student_cursor;
END;
Output:
Anu
Asha
Arpit
Chetan
Nihal
Total Records: 5
PL/SQL procedure successfully completed.
Example
CURSOR c1 IS SELECT empno, ename, job, sal
FROM emp
WHERE sal > 2000;
CURSOR c2 RETURN dept%ROWTYPE IS
SELECT * FROM dept WHERE deptno = 10;
CURSOR c3 (start_date DATE) IS
SELECT empno, sal FROM emp WHERE
hiredate > start_date;
Example
create table employee (
eno number constraint employee_pk primary key,
ename varchar2(50),
ebasic number,
dept varchar2(50)
)
INSERT INTO employee(eno, ename,ebasic,dept)
VALUES(1,'Dhaval Mehta',30000,'BCA')
INSERT INTO employee(eno, ename,ebasic,dept) VALUES(2,'Yash
Karanke',20000,'BCA')
INSERT INTO employee(eno, ename,ebasic,dept)
VALUES(3,'Hemal Shah',25000,'CSE')
INSERT INTO employee(eno, ename,ebasic,dept)
VALUES(4,'Aakash Gupta',22000,'IT')
Contd.,
create table employee_salary (
eno number,
ename varchar2(50),
commission number
)
Contd.,
DECLARE
eno employee.eno%type;
ename employee.ename%type;
ebasic employee.ebasic%type;
total float;
commission float;
CURSOR cdetails is
SELECT eno, ename,ebasic FROM
employee;
Contd.,
BEGIN
delete from employee_salary;
OPEN cdetails;
LOOP
total := 0;
FETCH cdetails into eno,ename,ebasic;
EXIT WHEN cdetails%notfound;
IF ebasic >28000 THEN
commission := ebasic * 0.20;
ELSIF ebasic >22000 THEN
commission := ebasic * 0.15;
ELSE
commission := ebasic * 0.10;
END IF;
Contd.,
total := ebasic + commission;
insert into employee_salary
values(eno,ename,total);
DBMS_OUTPUT.PUT_LINE('Employee Name : ' ||
ename || ' ->Basic Salary : ' || ebasic || ' -
>Commission : ' || commission ||' ->Total : ' ||
total );
END LOOP;
CLOSE cdetails;
END;
Example
DECLARE
v_emp_rec employees%ROWTYPE;
CURSOR cur_emp_name IS
SELECT *
FROM employees;
BEGIN
OPEN cur_emp_name;
LOOP
FETCH cur_emp_name INTO v_emp_rec;
exit WHEN cur_emp_name%NOTFOUND;
dbms_output.Put_line('Name: '
|| v_emp_rec.first_name
|| ' :: Salary: '
|| v_emp_rec.salary);
Example
DECLARE
r_product products%rowtype;
CURSOR c_product (low_price NUMBER, high_price NUMBER)
IS SELECT * FROM products
WHERE list_price BETWEEN low_price AND high_price;
BEGIN
-- show mass products
dbms_output.put_line('Mass products: ');
OPEN c_product(50,100);
LOOP
FETCH c_product INTO r_product;
EXIT WHEN c_product%notfound;
dbms_output.put_line(r_product.product_name || ': ' ||
r_product.list_price);
END LOOP;
Contd.,
CLOSE c_product;
-- show luxury products
dbms_output.put_line('Luxury products: ');
OPEN c_product(800,1000);
LOOP
FETCH c_product INTO r_product;
EXIT WHEN c_product%notfound;
dbms_output.put_line(r_product.product_name
|| ': ' ||r_product.list_price);
END LOOP;
CLOSE c_product;
END;
Example
Declare Cursor c1 (p_deptno number) is select
* from emp where deptno=p_deptno;
emp_rec emp%rowtype;
Begin
Open c1(10);
Loop
Fetch c1 into emp_rec;
Exit when c1%notfound;
Dbms_output.put_line(emp_rec.ename);
End loop;
Close c1;
End;
Example
Declare
Cursor c1 ( p_job varchar2) is select * from emp
where job=p_job;
Emp_mgr_rec emp%rowtype;
Begin
Open c1('MANAGER');
Loop
Fetch c1 into emp_mgr_rec;
Exit when c1%notfound;
Dbms_output.put_line(emp_mgr_rec.empno||',‘
||emp_mgr_rec.ename||‘,'||emp_mgr_rec.job);
End loop
Contd.,
Close c1;
Open c1('CLERK');
Loop Fetch c1 into i;
Exit when c1%notfound;
Dbms_output.put_line(i.empno||',‘
||i.ename||','||i.job);
End loop;
Close c1;
End
Cursor – For Loop
Declare
Cursor c1 is select * from emp;
I emp%rowtype;
Begin
For i in c1 loop
Dbms_output.put_line(i.empno||','||i.enam e);
End loop;
End
Example
Declare
Cursor c1 is select * from dept;
Cursor c2(p_deptno number) is select * from emp
where deptno=p_deptno;
Begin
For i in c1 Loop
Dbms_output.put_line(i.deptno);
For j in c2(i.deptno) Loop
Dbms_output.put_line(j.empno||
‘,'||j.ename||‘,'||j.sal);
End loop;
End loop;
End;
Example
Declare Cursor c1 is select * from employees; Begin
For i in c1
Loop
If i.job='CLERK'
then
Update employees set sal=i.sal+2500
where empno=i.empno;
Elsif i.job='MANAGER' then
Update employees set sal=i.sal+4500
where empno=i.empno;
End if;
End loop;
End;
Reference Cursors
Ref Cursor
Ref Cursors are user define types which is used to
process multiple records and also this is
record by record process
Generally through the static cursors we are using
only one select statement at a time for single
active set area where as in ref cursors we are executing
no of select statements dynamically for
single active set area.
Thats why these type of cursors are also called as
dynamic cursors.
By using ref cursors we return large amount of data
from oracle database into client
applications
Contd.,
There are 2 Types
Strong Ref Cursor
Weak Ref Cursor
Strong Ref Cursor
It is one of the ref cursor which is having
return type.
Weak Ref Cursor
It is one of the ref cursor which does not
have a return type.
Note : In ref cursor we are executing select
statements using open .... for statement