0% found this document useful (0 votes)
79 views25 pages

PL-SQL Cursors

1. A cursor is a buffer area used to process multiple records from a database table. It allows record-by-record processing. 2. There are two types of cursors: implicit cursors which are automatically created by Oracle for DML statements, and explicit cursors which are declared and manipulated by the user. 3. Explicit cursors allow the user to fetch multiple records from a table and process them using operations like loops and conditional statements. They are declared with the cursor name and query, opened to execute the query, records are fetched and processed, then the cursor is closed.

Uploaded by

Prabhanjan
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as DOCX, PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
79 views25 pages

PL-SQL Cursors

1. A cursor is a buffer area used to process multiple records from a database table. It allows record-by-record processing. 2. There are two types of cursors: implicit cursors which are automatically created by Oracle for DML statements, and explicit cursors which are declared and manipulated by the user. 3. Explicit cursors allow the user to fetch multiple records from a table and process them using operations like loops and conditional statements. They are declared with the cursor name and query, opened to execute the query, records are fetched and processed, then the cursor is closed.

Uploaded by

Prabhanjan
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as DOCX, PDF, TXT or read online on Scribd
You are on page 1/ 25

CURSORS:

********
-->Cursor is a buffer area which is used to process multiple
records and also record by record process.
-->It is not stored in database.
-->It is not Re-usable.

-->There are two types of cursors.

a)Implicit Cursor
b)Explicit Cursor

Implicit Cursor:
****************
-->SQL statements returns a single record is called implicit
cursor.
-->Implicit cursor operations done by the system whenever "DML"
operations are performed by user.
-->Open by the system
-->Fetch or retriecve the records by the system
-->close by the system.
-->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 attributes.
-->These cursors will create memory automatically to process
single row queries.
-->Oracle allocates memory, populates the data into that memory,
and deallocates that memory when the task is completed.
-->It also contains the predefined attributes in that memory to
perform various tasks (SQL%FOUND,SQL%NOTFOUND,SQL%ROWCOUNT).
-->IMPLICIT CURSOR TELLING US THE STATUS OF LAST DML COMMAND
WHETHER IT IS SUCCESSFULL OR NOT.
EX:
***
DECLARE
LV_ENAME VARCHAR2(20);
BEGIN
SELECT ENAME INTO LV_ENAME
FROM EMP
WHERE EMPNO=7369;
DBMS_OUTPUT.PUT_LINE(LV_ENAME);
END;
/

--Implicit Cursor

--pass the ou name and get org id(return the org id)

declare
lv_ou_name hr_operating_units.name%type;
lv_org_id hr_operating_units.organization_id%type;
begin
lv_ou_name:='Vision Operations';
--Implicit Cursor
select organization_id
into lv_org_id
from hr_operating_units
where 1=1
and name=lv_ou_name;
dbms_output.put_line('Organization Id is -->'||lv_org_id);
end;
/
--Implicit Cursor
--pass the ou name and get org id(return the org id)
declare

lv_ou_name hr_operating_units.name%type;
lv_org_id hr_operating_units.organization_id%type;

begin
lv_ou_name:='Vision Operations1';

--dbms_output.put_line('lv_ou_name is -->'||lv_ou_name);

--Implicit Cursor

select organization_id
into lv_org_id
from hr_operating_units
where 1=1
and name=lv_ou_name;

dbms_output.put_line('Organization Id is -->'||lv_org_id);
end;
/

IMPLICIT Cursor Attributes:


***************************
-->It supports %isopen, %found,%notfound,%rowcount attributes.
-->%found returns TRUE if DML is success.
-->%notfound returns TRUE if DML is failure.
-->%rowcount returns no.of rows manipulated by DML statement.

simple program:
***************

begin
update emp1 set sal = sal + 2000
where empno = 790;
dbms_output.put_line(' Employ Updated ');
end;

-->In above program we are unable to find DML stmt Status.


-->Using Implicit cursor attributes it is possible to know the
status.
/
declare
--vdept number(2) := &dept;
begin
update emp1 set sal = sal + 1000
where empno = 790;
if sql%Notfound then
dbms_output.put_line('Unable to Update rows - No
such empno exists');
else
dbms_output.put_line(sql%rowcount||' Employees are updated
sucessfully ');
--commit;
end if;
end;
/
--SQL%ROWCOUNT and SQL%NOTFOUND:
********************************
declare
vdept number(2) := &dept;
begin
update emp1 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;
/
Using Implicit cursors:

-->pl/sql block Trapping Update stmt status.


declare
vdept number(2) := &dept;
begin
delete from emp1 where deptno = vdept;
if sql%rowcount > 3 then
dbms_output.put_line(' Invalid operation - cannot remove more
than 3 employees ');
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 .

--SQL%ROWCOUNT:
***************

DECLARE
LV_ENAME EMP.ENAME%TYPE;
LV_SAL EMP.SAL%TYPE;
BEGIN

SELECT ENAME,SAL
INTO LV_ENAME,LV_SAL
FROM EMP
WHERE EMPNO=7839;
DBMS_OUTPUT.PUT_LINE('Number of rows Processed : '||SQL%ROWCOUNT);
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 employees ');
rollback;
else
dbms_output.put_line(sql%rowcount||' Employees are removed');
-- commit;
end if;
end;

%FOUND,%NOTFOUND,%ROWCOUNT:
***************************

DECLARE
LV_TOT_CNT NUMBER;
BEGIN
UPDATE EMP1
SET SAL=SAL+200;
--Checking Implicit cursor data using %NOTFOUND attribute
if SQL%NOTFOUND THEN
DBMS_OUTPUT.PUT_LINE('None of the emplyee salaries are not
updated');
--Checking Implicit cursor data using %FOUND attribute
elsif SQL%FOUND then
--getting rowcount using %ROWCOUNT Attribute
LV_TOT_CNT:=SQL%ROWCOUNT;
DBMS_OUTPUT.PUT_LINE('Total number of employees are updated : '||
LV_TOT_CNT);
end if;
END;
/
Explicit Cursor:
****************
-->SQL statements return a multiple records is called Explicit
Cursor.
-->Explicit cursor operations are done by user.
-->declare by the user
-->open by the user
-->fetch the records by the user
-->close by the user.

Cursor operations:
******************
a)declare
b)open
c)fetch
d)close

DECLARE:
********
-->In declare section of the pl/sql block we are defining cusrors
using following syntax.

syntax:
*******

cursor cursorname is select <column name> from tablename where


condition;

OPEN:
*****
-->whenever we are opening the cursor then only oracle server
fetch data from table into cursor memory area because whenever we
are opening the cursor then only select statements are executed.

syntax:
*******
open cursorname;

-->the statement is used in executable section of the pl/sal


block.

FETCH:
******
-->Using fetch statement we are fetching data from cursor into
pl/sql variables.

syntax:
*******

fetch cursorname into variable1,variable2,...;

CLOSE:
******
-->when we are closing the cursor all resorces aallocated from
cursor memory area automatically released.

syntax:
*******

close cursorname;

EX1:
****
DECLARE
CURSOR C1 IS SELECT ENAME,SAL FROM EMP;
LV_ENAME VARCHAR2(20);
LV_SAL VARCHAR2(10);
BEGIN
OPEN C1;
FETCH C1 INTO LV_ENAME,LV_SAL;
DBMS_OUTPUT.PUT_LINE(LV_ENAME||','||LV_SAL);
CLOSE C1;
END;
/
EX2:
****
cursor cursorname is select <column name> from tablename where
condition;
open cursorname;
fetch cursorname into variable1,variable2,...;
close cursorname;
/
DECLARE
CURSOR C1 IS SELECT ENAME,SAL FROM EMP;
LV_ENAME EMP.ENAME%TYPE;
LV_SAL EMP.SAL%TYPE;
BEGIN
OPEN C1;
FETCH C1 INTO LV_ENAME,LV_SAL;
DBMS_OUTPUT.PUT_LINE(LV_ENAME||','||LV_SAL);
FETCH C1 INTO LV_ENAME,LV_SAL;
DBMS_OUTPUT.PUT_LINE(LV_ENAME||','||LV_SAL);
FETCH C1 INTO LV_ENAME,LV_SAL;
DBMS_OUTPUT.PUT_LINE(LV_ENAME||','||LV_SAL);
FETCH C1 INTO LV_ENAME,LV_SAL;
DBMS_OUTPUT.PUT_LINE(LV_ENAME||','||LV_SAL);
FETCH C1 INTO LV_ENAME,LV_SAL;
DBMS_OUTPUT.PUT_LINE(LV_ENAME||','||LV_SAL);
FETCH C1 INTO LV_ENAME,LV_SAL;
DBMS_OUTPUT.PUT_LINE(LV_ENAME||','||LV_SAL);
FETCH C1 INTO LV_ENAME,LV_SAL;
DBMS_OUTPUT.PUT_LINE(LV_ENAME||','||LV_SAL);
FETCH C1 INTO LV_ENAME,LV_SAL;
DBMS_OUTPUT.PUT_LINE(LV_ENAME||','||LV_SAL);
FETCH C1 INTO LV_ENAME,LV_SAL;
DBMS_OUTPUT.PUT_LINE(LV_ENAME||','||LV_SAL);
FETCH C1 INTO LV_ENAME,LV_SAL;
DBMS_OUTPUT.PUT_LINE(LV_ENAME||','||LV_SAL);
FETCH C1 INTO LV_ENAME,LV_SAL;
DBMS_OUTPUT.PUT_LINE(LV_ENAME||','||LV_SAL);
FETCH C1 INTO LV_ENAME,LV_SAL;
DBMS_OUTPUT.PUT_LINE(LV_ENAME||','||LV_SAL);
FETCH C1 INTO LV_ENAME,LV_SAL;
DBMS_OUTPUT.PUT_LINE(LV_ENAME||','||LV_SAL);
FETCH C1 INTO LV_ENAME,LV_SAL;
DBMS_OUTPUT.PUT_LINE(LV_ENAME||','||LV_SAL);
CLOSE C1;
END;
/
EX3:
****
--TO FETCH MULTIPLE ROWS FROM EMP TABLE BY USING LOOPING
STATEMENTS ?
DECLARE
CURSOR C1 IS SELECT ENAME,SAL FROM EMP;
LV_ENAME VARCHAR2(20);
LV_SAL VARCHAR2(10);
BEGIN
OPEN C1;
LOOP
FETCH C1 INTO LV_ENAME,LV_SAL;
DBMS_OUTPUT.PUT_LINE(LV_ENAME||','||LV_SAL);
END LOOP;
CLOSE C1;
END;
/
EX4:
****
--TO FETCH MULTIPLE ROWS FROM EMP TABLE BY USING LOOPING
STATEMENTS USING EXIT?
-- it is an infinite loop.so that we need break a loop then we are
using "EXIT" statement.

DECLARE
--cursor cursorname is select <column name> from tablename where
condition;
CURSOR C1 IS SELECT ENAME,SAL FROM EMP;
LV_ENAME EMP.ENAME%TYPE;
LV_SAL EMP.SAL%TYPE;
BEGIN
--open cursorname;
OPEN C1;
LOOP
--fetch cursorname into variable1,variable2,...;
FETCH C1 INTO LV_ENAME,LV_SAL;
EXIT WHEN C1%NOTFOUND;
DBMS_OUTPUT.PUT_LINE(LV_ENAME||','||LV_SAL);
END LOOP;
--close cursorname;
CLOSE C1;
END;
/
EX5:
*****
DECLARE
CURSOR C1 IS SELECT * FROM EMP;
I EMP%ROWTYPE;
BEGIN
OPEN C1;
LOOP
FETCH C1 INTO I;
EXIT WHEN C1%NOTFOUND;
IF I.SAL>2000 THEN
DBMS_OUTPUT.PUT_LINE('High Sal : '||I.SAL);
END IF;
END LOOP;
CLOSE C1;
END;
/
EX6:
****
CREATE TABLE XX_EMP(NAME VARCHAR2(20),SAL NUMBER);
--TO TRANSFER THE DATA FROM ONE TABLE TO ANOTHER TABLE

DECLARE
CURSOR C1 IS SELECT * FROM EMP WHERE SAL>2000;
I EMP%ROWTYPE;
BEGIN
OPEN C1;
LOOP
FETCH C1 INTO I;
EXIT WHEN C1%NOTFOUND;
INSERT INTO XX_EMP VALUES (I.ENAME,I.SAL);
END LOOP;
CLOSE C1;
END;
/
DECLARE
CURSOR C1 IS SELECT * FROM EMP WHERE SAL>2000;
I EMP%ROWTYPE;
LV_TOT_CNT NUMBER:=0;
LV_CNT NUMBER;
BEGIN
BEGIN
SELECT COUNT(*)
INTO LV_CNT
FROM EMP
WHERE SAL>2000;
DBMS_OUTPUT.PUT_LINE('TOTAL COUNT :'||LV_CNT);
END;
OPEN C1;
LOOP
FETCH C1 INTO I;
EXIT WHEN C1%NOTFOUND;
LV_TOT_CNT:=LV_TOT_CNT+1;
INSERT INTO XX_EMP VALUES (I.ENAME,I.SAL);
END LOOP;
DBMS_OUTPUT.PUT_LINE('NUMBER OF ROWS NSERTED : '||LV_TOT_CNT);
--DBMS_OUTPUT.PUT_LINE('NUMBER OF ROWS NSERTED : '||C1%ROWCOUNT);
--LV_TOT_CNT:=C1%ROWCOUNT;
--DBMS_OUTPUT.PUT_LINE('NUMBER OF ROWS NSERTED : '||LV_TOT_CNT);
CLOSE C1;
END;
/
EX7:
****
--Pl/sql Block calculates new commission for ALL employees using
Explicit Cursors:

declare
cursor c1 is select empno,ename,comm from emp1
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 emp1 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;
/
EX8:
****
--TO FETCH THE DATA FROM BASE TABLE (PO_HEADERS_ALL)

DECLARE
--cursor cursorname is select <column name> from tablename where
condition;
CURSOR C1 IS select po_header_id,segment1 from po_headers_all;
lv_po_header_id number;
lv_segment1 varchar2(20);
BEGIN
--open cursorname;
OPEN C1;
LOOP
--fetch cursorname into variable1,variable2,...;
FETCH C1 INTO lv_segment1,lv_po_header_id;
EXIT WHEN C1%NOTFOUND;
DBMS_OUTPUT.PUT_LINE(lv_segment1||','||lv_po_header_id);
END LOOP;
--close cursorname;
CLOSE C1;
END;
/
DECLARE
--cursor cursorname is select <column name> from tablename where
condition;
CURSOR C1 IS SELECT po_header_id,segment1 FROM (select ROWNUM
R,po_header_id,segment1 from po_headers_all) WHERE R>40 AND
R<=100;
lv_po_header_id number;
lv_segment1 varchar2(20);
BEGIN
--open cursorname;
OPEN C1;
LOOP
--fetch cursorname into variable1,variable2,...;
FETCH C1 INTO lv_segment1,lv_po_header_id;
EXIT WHEN C1%NOTFOUND;
DBMS_OUTPUT.PUT_LINE(lv_segment1||','||lv_po_header_id);
END LOOP;
--close cursorname;
CLOSE C1;
END;
/
EX9:
****
--TO FETCH THE DATA FROMBASE TABLE (HR_OPERATING_UNITS)
DECLARE
--cursor cursorname is select <column name> from tablename where
condition;
CURSOR C1 IS SELECT name,organization_id FROM hr_operating_units;
LV_NAME VARCHAR2(50);
lv_organization_id varchar2(20);
BEGIN
--open cursorname;
OPEN C1;
LOOP
--fetch cursorname into variable1,variable2,...;
FETCH C1 INTO LV_NAME,lv_organization_id;
EXIT WHEN C1%NOTFOUND;
DBMS_OUTPUT.PUT_LINE(LV_NAME||','||lv_organization_id);
END LOOP;
--close cursorname;
CLOSE C1;
END;
/
DECLARE
CURSOR C1 IS SELECT * FROM DEPT;
CURSOR C2 IS SELECT * FROM EMP;
CURSOR C3 IS SELECT * FROM PO_HEADERS_ALL WHERE ROWNUM<10;
I DEPT%ROWTYPE;
J EMP%ROWTYPE;
K PO_HEADERS_ALL%ROWTYPE;
LV_DEPT_CNT NUMBER;
LV_EMP_CNT NUMBER;
LV_PO_CNT NUMBER;
BEGIN
BEGIN
SELECT COUNT(*)
INTO LV_DEPT_CNT
FROM DEPT;
DBMS_OUTPUT.PUT_LINE('TOATAL DEPT COUNT :'||LV_DEPT_CNT);
END;
OPEN C1;
DBMS_OUTPUT.PUT_LINE('DEPT DETAILS PROGRAM START :'||
TO_CHAR(SYSDATE,'DD-MON-YYYY HH24:MI:SS'));
LOOP
FETCH C1 INTO I;
EXIT WHEN C1%NOTFOUND;
DBMS_OUTPUT.PUT_LINE(I.DEPTNO||','||I.DNAME||','||I.LOC);
END LOOP;
DBMS_OUTPUT.PUT_LINE('DEPT DETAILS PROGRAM END :');
CLOSE C1;
BEGIN
SELECT COUNT(*)
INTO LV_EMP_CNT
FROM EMP;
DBMS_OUTPUT.PUT_LINE('TOATAL DEPT COUNT :'||LV_EMP_CNT);
END;
OPEN C2;
DBMS_OUTPUT.PUT_LINE('EMP DETAILS PROGRAM START :'||
TO_CHAR(SYSDATE,'DD-MON-YYYY HH24:MI:SS'));
LOOP
FETCH C2 INTO J;
EXIT WHEN C2%NOTFOUND;
DBMS_OUTPUT.PUT_LINE(J.EMPNO||','||J.ENAME||','||J.SAL);
END LOOP;
DBMS_OUTPUT.PUT_LINE('EMP DETAILS PROGRAM END :');
CLOSE C2;
BEGIN
SELECT COUNT(*)
INTO LV_PO_CNT
FROM PO_HEADERS_ALL;
DBMS_OUTPUT.PUT_LINE('TOATAL DEPT COUNT :'||LV_PO_CNT);
END;
OPEN C3;
DBMS_OUTPUT.PUT_LINE('PO DETAILS PROGRAM START :'||
TO_CHAR(SYSDATE,'DD-MON-YYYY HH24:MI:SS'));
LOOP
FETCH C3 INTO K;
EXIT WHEN C3%NOTFOUND;
DBMS_OUTPUT.PUT_LINE(K.PO_HEADER_ID||','||K.SEGMENT1||','||
K.TYPE_LOOKUP_CODE);
END LOOP;
DBMS_OUTPUT.PUT_LINE('PO DETAILS PROGRAM END :');
CLOSE C3;
END;
/
BY USING WHILE LOOP:
======================
DECLARE
CURSOR C1 IS SELECT ENAME,SAL FROM EMP;
Lv_ENAME VARCHAR2(10);
Lv_SAL NUMBER(10);
BEGIN
OPEN C1;
FETCH C1 INTO Lv_ENAME,Lv_SAL;------------LOOP START FROM 1st ROW
WHILE(C1%FOUND)
LOOP
DBMS_OUTPUT.PUT_LINE(Lv_ENAME||','||Lv_SAL);
FETCH C1 INTO Lv_ENAME,Lv_SAL;------------LOOP CONTINUE UPTO LAST
ROW
END LOOP;
CLOSE C1;
END;
/
EXPLICIT CURSOR ATTRIBUTES:
***************************
-->explicit cusrsor having following attributes

1)%notfound
2)%found
3)%isopen
4)%rowcount

-->all the above cursor attributes using along with cursor name
only.

syntax:
********
cursorname%attributename

NOTE:
*****
-->except %rowcount all other cursor attribute records boolean
value return eithere true or false
-->where as %rowcount returns number datatype.
%notfound:
**********
-->this attribute returns true when cursor does not have data
after fetching records from cursor.

EX:
***
DECLARE
CURSOR C1 IS SELECT ENAME,SAL FROM EMP;
LV_ENAME VARCHAR2(20);
LV_SAL VARCHAR2(10);
BEGIN
OPEN C1;
LOOP
FETCH C1 INTO LV_ENAME,LV_SAL;
EXIT WHEN C1%NOTFOUND;
DBMS_OUTPUT.PUT_LINE(LV_ENAME||','||LV_SAL);
END LOOP;
CLOSE C1;
END;

%FOUND:
********
-->Returns true if a succesful fetch has been executed
-->Returns false if no row was fetched

EX:
***

DECLARE
CURSOR C1 IS SELECT * FROM EMP;
I EMP%ROWTYPE;
BEGIN
OPEN C1;
LOOP
FETCH C1 INTO I;
IF C1%FOUND THEN
DBMS_OUTPUT.PUT_LINE(I.EMPNO||','||I.ENAME);
ELSE
EXIT;
END IF;
END LOOP;
CLOSE C1;
END;

%ISOPEN
*******
-->Returns true if the cursor is open
-->Returns false if the cursor is closed

EX:
***
DECLARE
CURSOR C1 IS SELECT * FROM EMP;
I EMP%ROWTYPE;
BEGIN
OPEN C1;
IF C1%ISOPEN THEN
DBMS_OUTPUT.PUT_LINE('CURSOR IS OPENED');
LOOP
FETCH C1 INTO I;
IF C1%FOUND THEN
DBMS_OUTPUT.PUT_LINE(I.ENAME||','||I.SAL||','||I.JOB);
ELSE
EXIT;
END IF;
END LOOP;
CLOSE C1;
IF NOT C1%ISOPEN THEN
DBMS_OUTPUT.PUT_LINE('CURSOR IS CLOSED');
END IF;
END IF;
END;

%ROWCOUNT:
**********
-->Returns number of rows fetched by the cursor

DECLARE
CURSOR C1 IS SELECT * FROM EMP;
I EMP%ROWTYPE;
BEGIN
OPEN C1;
LOOP
FETCH C1 INTO I;
EXIT WHEN C1%NOTFOUND;
DBMS_OUTPUT.PUT_LINE(I.EMPNO||','||I.ENAME);
--DBMS_OUTPUT.PUT_LINE(C1%ROWCOUNT||' : '||'Total number of
employees are: ');
END LOOP;
DBMS_OUTPUT.PUT_LINE('Total number of employees are: '||
C1%ROWCOUNT);
CLOSE C1;
END;

CURSOR WITH FOR LOOP:


*********************
-->In cursor for loop no need to open,fetch and close the cursor.
-->for loop is executed in executable section of the pl/sql block.
-->Improves performance.

syntax:
*******
for indexvariable in cursorname
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

EX:
***
BY USING FOR LOOP:
******************
DECLARE
CURSOR C1 IS SELECT * FROM EMP;
BEGIN
FOR I IN C1
LOOP
DBMS_OUTPUT.PUT_LINE(I.EMPNO||','||I.ENAME);
END LOOP;
END;
/
--TO FETCH THE DATA FROM OE_ORDER_HEADERS_ALL

DECLARE
CURSOR C1 IS SELECT * FROM OE_ORDER_HEADERS_ALL WHERE ROWNUM<=100;
BEGIN
FOR I IN C1
LOOP
DBMS_OUTPUT.PUT_LINE(I.ORDER_NUMBER||','||I.ORG_ID||','||
I.ORDERED_DATE);
END LOOP;
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
Lopay Hipay ');
for k in c3 loop
dbms_output.put_line(k.empno||' '||k.ename
||' '||k.job||' '||k.sal||' '||k.lopay||' '||k.hipay);
end loop;
end;
/
DECLARE
CURSOR C1 IS SELECT * FROM EMP;
LV_COUNT NUMBER :=0;
BEGIN
FOR I IN C1
LOOP
LV_COUNT :=LV_COUNT+1;
INSERT INTO XX_EMP
(
NAME,
SAL
)
VALUES
(
I.ENAME,
I.SAL
);
END LOOP;
COMMIT;
DBMS_OUTPUT.PUT_LINE('TOTAL NUMBER OF RECORDS ARE INSERTED :'||
LV_COUNT);
END;
/
--We can also eliminate declare section of the cursor using for
loop in this case we are using select statements in place of
cursorname in cursor for loop.

BEGIN
FOR I IN (SELECT * FROM EMP)
LOOP
DBMS_OUTPUT.PUT_LINE(I.ENAME||','||I.SAL);
END LOOP;
END;
/
MUTIPLE CURSOR WITH FOR LOOP:
****************************

DECLARE
CURSOR C1 IS SELECT * FROM DEPT;
CURSOR C2 IS SELECT * FROM EMP;
BEGIN
FOR I IN C1
LOOP
DBMS_OUTPUT.PUT_LINE(I.DEPTNO||','||I.DNAME||','||I.LOC);
--END LOOP;
FOR J IN C2
LOOP
DBMS_OUTPUT.PUT_LINE(J.EMPNO||','||J.ENAME||','||J.JOB);
END LOOP;
END LOOP;
END;
/
DECLARE
CURSOR C1 IS SELECT * FROM DEPT;
CURSOR C2 IS SELECT * FROM EMP;
BEGIN
DBMS_OUTPUT.PUT_LINE('DEPT DETAILS');
FOR I IN C1
LOOP
DBMS_OUTPUT.PUT_LINE(I.DEPTNO||','||I.DNAME||','||I.LOC);
END LOOP;
DBMS_OUTPUT.PUT_LINE('EMP DETAILS');
FOR J IN C2
LOOP
DBMS_OUTPUT.PUT_LINE(J.EMPNO||','||J.ENAME||','||J.JOB);
END LOOP;
END;
/
declare
cursor c1 is
select
aia.INVOICE_NUM,aia.INVOICE_ID,aia.INVOICE_AMOUNT,aps.VENDOR_NAME,
aps.segment1,assa.VENDOR_SITE_CODE,hou.name
from ap_invoices_all aia,
ap_suppliers aps,
ap_supplier_sites_all assa,
hr_operating_units hou
where 1=1
and aia.VENDOR_ID=aps.VENDOR_ID
and aps.VENDOR_ID=assa.VENDOR_ID
and aia.VENDOR_SITE_ID=assa.VENDOR_SITE_ID
and hou.organization_id=aia.org_id;
--and invoice_num='ERS-9163-109073';
begin
for i in c1
loop
dbms_output.put_line(i.INVOICE_NUM||','||i.INVOICE_ID||','||
i.INVOICE_AMOUNT||','||i.VENDOR_NAME);
end loop;
end;
/
declare
cursor c1 is
select
poh.PO_HEADER_ID,pol.PO_LINE_ID,pol.LINE_NUM,pol.ITEM_DESCRIPTION
from po_headers_all poh,
po_lines_all pol
where poh.po_header_id=pol.po_header_id
and poh.po_header_id=3533;
begin
for i in c1
loop
dbms_output.put_line(i.PO_HEADER_ID||','||i.PO_LINE_ID||','||
i.LINE_NUM||','||i.ITEM_DESCRIPTION);
end loop;
end;
/
PARAMETER CURSOR:
*****************
-->Passing a parameter in cursor is called parameter cursor.
-->At this cursor it will allow a user to pass the data extracted
from 1 cursor to the other cursor thru arguments.
-->Parameter specification is provided at Declaration of cursor
and when the cursor gets opened.

syntax:
*******
cursor cursorname(parametername datatype) is select * from
tablename where columnname=parametername;

--normal explicit cursor

DECLARE
CURSOR C1 IS SELECT * FROM EMP;
I EMP%ROWTYPE;
BEGIN
OPEN C1;
LOOP
FETCH C1 INTO I;
EXIT WHEN C1%NOTFOUND;
DBMS_OUTPUT.PUT_LINE(I.EMPNO||','||I.ENAME);
END LOOP;
CLOSE C1;
END;
/
--same program we are PASSING JOB TYPE

DECLARE
CURSOR C1 IS SELECT * FROM EMP where job='CLERK';
I EMP%ROWTYPE;
BEGIN
OPEN C1;
LOOP
FETCH C1 INTO I;
EXIT WHEN C1%NOTFOUND;
DBMS_OUTPUT.PUT_LINE(I.EMPNO||','||I.ENAME||','||I.JOB);
END LOOP;
CLOSE C1;
END;
/

--Same program we need to pass parmaeter at run time &job (it


indicates to ask as run time value)

DECLARE
CURSOR C1 IS SELECT * FROM EMP where job=&JOB;
I EMP%ROWTYPE;
BEGIN
OPEN C1;
LOOP
FETCH C1 INTO I;
EXIT WHEN C1%NOTFOUND;
DBMS_OUTPUT.PUT_LINE(I.EMPNO||','||I.ENAME||','||I.JOB);
END LOOP;
CLOSE C1;
END;
/
--Parameter cursor

DECLARE
CURSOR C1(P_JOB VARCHAR2) IS SELECT * FROM EMP where job=P_JOB;
I EMP%ROWTYPE;
BEGIN
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;
OPEN C1('MANAGER');
LOOP
FETCH C1 INTO I;
EXIT WHEN C1%NOTFOUND;
DBMS_OUTPUT.PUT_LINE(I.EMPNO||','||I.ENAME||','||I.JOB);
END LOOP;
CLOSE C1;
END;
/
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('===============================');
DBMS_OUTPUT.PUT_LINE(I.DEPTNO||','||I.DNAME||','||I.LOC);
DBMS_OUTPUT.PUT_LINE('===============================');

FOR J IN C2(I.DEPTNO)
LOOP
DBMS_OUTPUT.PUT_LINE(J.DEPTNO||','||J.EMPNO||','||J.ENAME||','||
J.JOB);
END LOOP;
END LOOP;
END;

/
DECLARE
CURSOR C1 IS SELECT * FROM PO_HEADERS_ALL WHERE PO_HEADER_ID=3533;
CURSOR C2(P_PO_HEADER_ID NUMBER) IS SELECT * FROM PO_LINES_ALL
WHERE PO_HEADER_ID=P_PO_HEADER_ID;
BEGIN
FOR I IN C1
LOOP
DBMS_OUTPUT.PUT_LINE('===============================');
DBMS_OUTPUT.PUT_LINE(I.PO_HEADER_ID||','||I.SEGMENT1);
DBMS_OUTPUT.PUT_LINE('===============================');

FOR J IN C2(I.PO_HEADER_ID)
LOOP
DBMS_OUTPUT.PUT_LINE(J.PO_HEADER_ID||','||J.PO_LINE_ID||','||
J.LINE_NUM||','||J.ITEM_DESCRIPTION);
END LOOP;
END LOOP;
END;
/
REF CURSORS:
************
-->Ref Cursors are user defined types which is used to process
multiple records.

-->Generally the static cursors we are using only one select


statement at a time for single active set area.

-->In refcursors we are executing no.of select statements


dynamically for a single active set area.That's why these type of
cursors are also called as dynamic cursors.

-->Refcursors are user defined type so we are creating in two step


process.
-->First we are creating type and then only we are creating a
variable of that type.That's why these type of cursors are also
called as cursor variables.

-->There are two types of refcursors supported by oracle.


1)Strong Refcursor
2)Weak Refcursor

-->Strong Refcursor is a refcursor which having a return type.


-->Weak Refcursor is a refcursor which doesn't have a return type.

Syntax:
*******
Type Typename is ref cursor return recordtypedatatype; --Strong
Ref cursor
Type Typename is ref cursor; --Weak ref cursor

Note:
*****
-->In ref cursors we are executing select statements using
open...for statements.

-->These atatements are executed in executable section of the


pl/sql block.

--normal cursor

DECLARE
CURSOR EMP_NAME IS SELECT ENAME FROM EMP;
CURSOR DEPT_NAME IS SELECT DNAME FROM DEPT;
LV_NAME VARCHAR2(50);
BEGIN
DBMS_OUTPUT.PUT_LINE('*********EMP DETAILS**********');
OPEN EMP_NAME;
LOOP
FETCH EMP_NAME INTO LV_NAME;
EXIT WHEN EMP_NAME%NOTFOUND;
DBMS_OUTPUT.PUT_LINE(LV_NAME);
END LOOP;
CLOSE EMP_NAME;
DBMS_OUTPUT.PUT_LINE('*********DEPT DETAILS**********');
OPEN DEPT_NAME;
LOOP
FETCH DEPT_NAME INTO LV_NAME;
EXIT WHEN DEPT_NAME%NOTFOUND;
DBMS_OUTPUT.PUT_LINE(LV_NAME);
END LOOP;
CLOSE DEPT_NAME;
END;
/

EX:
***
--WEAK REF CURSOR

DECLARE
TYPE T1 IS REF CURSOR;
V_T T1;
I EMP%ROWTYPE;
BEGIN
OPEN V_T FOR SELECT * FROM EMP;
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;
/
--WEAK REF CURSOR FOR SPECIFIC COLUMN
DECLARE
TYPE XX_REF_CUR_TYPE IS REF CURSOR;
C_REF_CUR XX_REF_CUR_TYPE;
LV_VAR1_TYPE VARCHAR2(30);
LV_VAR2_TYPE VARCHAR2(20);
BEGIN
DBMS_OUTPUT.PUT_LINE('***************EMPLOYEE
DETAILS*************');
OPEN C_REF_CUR FOR SELECT ENAME,SAL FROM EMP;
LOOP
FETCH C_REF_CUR INTO LV_VAR1_TYPE,LV_VAR2_TYPE;
EXIT WHEN C_REF_CUR%NOTFOUND;
DBMS_OUTPUT.PUT_LINE(C_REF_CUR%ROWCOUNT||'-'||LV_VAR1_TYPE||'|
Salary is :'|| LV_VAR2_TYPE);
END LOOP;
CLOSE C_REF_CUR;
DBMS_OUTPUT.PUT_LINE('***************DEPARTMENT
DETAILS*************');
OPEN C_REF_CUR FOR SELECT DNAME,DEPTNO FROM DEPT;
LOOP
FETCH C_REF_CUR INTO LV_VAR1_TYPE,LV_VAR2_TYPE;
EXIT WHEN C_REF_CUR%NOTFOUND;
DBMS_OUTPUT.PUT_LINE(C_REF_CUR%ROWCOUNT||'-'||LV_VAR1_TYPE||'|
Deptno is :'|| LV_VAR2_TYPE);
END LOOP;
CLOSE C_REF_CUR;
DBMS_OUTPUT.PUT_LINE('***************PO_HEADERS_ALL
DETAILS*************');
OPEN C_REF_CUR FOR SELECT PO_HEADER_ID,SEGMENT1 FROM
PO_HEADERS_ALL WHERE ROWNUM<=10;
LOOP
FETCH C_REF_CUR INTO LV_VAR1_TYPE,LV_VAR2_TYPE;
EXIT WHEN C_REF_CUR%NOTFOUND;
DBMS_OUTPUT.PUT_LINE(C_REF_CUR%ROWCOUNT||'-'||LV_VAR1_TYPE||'|
Deptno is :'|| LV_VAR2_TYPE);
END LOOP;
CLOSE C_REF_CUR;
END;
/
--WEAK REFCURSOR FOR ROWTYPE
DECLARE
TYPE XX_REF_CUR_TYPE IS REF CURSOR;
C_REF_CUR XX_REF_CUR_TYPE;
LV_EMP_TYPE EMP%ROWTYPE;
LV_DEPT_TYPE DEPT%ROWTYPE;
BEGIN
DBMS_OUTPUT.PUT_LINE('*****************CURSOR1
DETAILS*****************');
OPEN C_REF_CUR FOR SELECT * FROM EMP;
LOOP
FETCH C_REF_CUR INTO LV_EMP_TYPE;
EXIT WHEN C_REF_CUR%NOTFOUND;
DBMS_OUTPUT.PUT_LINE(LV_EMP_TYPE.EMPNO||'-'||
LV_EMP_TYPE.ENAME||'-'||LV_EMP_TYPE.JOB);
END LOOP;
CLOSE C_REF_CUR;
DBMS_OUTPUT.PUT_LINE('*****************CURSOR2
DETAILS*****************');
OPEN C_REF_CUR FOR SELECT * FROM DEPT;
LOOP
FETCH C_REF_CUR INTO LV_DEPT_TYPE;
EXIT WHEN C_REF_CUR%NOTFOUND;
DBMS_OUTPUT.PUT_LINE(LV_DEPT_TYPE.DEPTNO||'-'||
LV_DEPT_TYPE.DNAME||'-'||LV_DEPT_TYPE.LOC);
END LOOP;
CLOSE C_REF_CUR;
END;
/
DECLARE
TYPE XX_REF_CUR_TYPE IS REF CURSOR;
C_REF_CUR XX_REF_CUR_TYPE;
LV_EMP_TYPE EMP%ROWTYPE;
LV_DEPT_TYPE DEPT%ROWTYPE;
LV_HR_UNITS HR_OPERATING_UNITS%ROWTYPE;
BEGIN
DBMS_OUTPUT.PUT_LINE('*****************CURSOR1
DETAILS*****************');
OPEN C_REF_CUR FOR SELECT * FROM EMP;
LOOP
FETCH C_REF_CUR INTO LV_EMP_TYPE;
EXIT WHEN C_REF_CUR%NOTFOUND;
DBMS_OUTPUT.PUT_LINE(LV_EMP_TYPE.EMPNO||'-'||
LV_EMP_TYPE.ENAME||'-'||LV_EMP_TYPE.JOB);
END LOOP;
CLOSE C_REF_CUR;
DBMS_OUTPUT.PUT_LINE('*****************CURSOR2
DETAILS*****************');
OPEN C_REF_CUR FOR SELECT * FROM DEPT;
LOOP
FETCH C_REF_CUR INTO LV_DEPT_TYPE;
EXIT WHEN C_REF_CUR%NOTFOUND;
DBMS_OUTPUT.PUT_LINE(LV_DEPT_TYPE.DEPTNO||'-'||
LV_DEPT_TYPE.DNAME||'-'||LV_DEPT_TYPE.LOC);
END LOOP;
CLOSE C_REF_CUR;
DBMS_OUTPUT.PUT_LINE('*****************CURSOR3
DETAILS*****************');
OPEN C_REF_CUR FOR SELECT * FROM HR_OPERATING_UNITS;
LOOP
FETCH C_REF_CUR INTO LV_HR_UNITS;
EXIT WHEN C_REF_CUR%NOTFOUND;
DBMS_OUTPUT.PUT_LINE(LV_HR_UNITS.NAME);
END LOOP;
CLOSE C_REF_CUR;
END;

---STRONG REF CURSOR

DECLARE
TYPE XX_REF_CUR_TYPE IS REF CURSOR RETURN EMP%ROWTYPE;
C_REF_CUR XX_REF_CUR_TYPE;

LV_EMP_TYPE EMP%ROWTYPE;
LV_DEPT_TYPE DEPT%ROWTYPE;

BEGIN
DBMS_OUTPUT.PUT_LINE('*****************CURSOR1
DETAILS*****************');
OPEN C_REF_CUR FOR SELECT * FROM EMP;
LOOP
FETCH C_REF_CUR INTO LV_EMP_TYPE;
EXIT WHEN C_REF_CUR%NOTFOUND;
DBMS_OUTPUT.PUT_LINE(LV_EMP_TYPE.EMPNO||'-'||
LV_EMP_TYPE.ENAME||'-'||LV_EMP_TYPE.JOB);
END LOOP;
CLOSE C_REF_CUR;
END;
/
--STRONG REF CURSOR USING DIFFERENT TABLE TYPE(It will throw the
error)

DECLARE
TYPE XX_REF_CUR_TYPE IS REF CURSOR RETURN EMP%ROWTYPE;
C_REF_CUR XX_REF_CUR_TYPE;

LV_EMP_TYPE EMP%ROWTYPE;
LV_DEPT_TYPE DEPT%ROWTYPE;

BEGIN
DBMS_OUTPUT.PUT_LINE('*****************CURSOR1
DETAILS*****************');
OPEN C_REF_CUR FOR SELECT * FROM DEPT;
LOOP
FETCH C_REF_CUR INTO LV_DEPT_TYPE;
EXIT WHEN C_REF_CUR%NOTFOUND;
DBMS_OUTPUT.PUT_LINE(LV_DEPT_TYPE.DEPTNO||'-'||
LV_DEPT_TYPE.DNAME||'-'||LV_DEPT_TYPE.LOC);
END LOOP;
CLOSE C_REF_CUR;
END;
/
--SYS REFCURSOR --IS ALWAYS WEAKLY TYPE REF CURSOR

DECLARE
--TYPE XX_REF_CUR_TYPE IS REF CURSOR; -- RETURN EMP%ROWTYPE;
C_REF_CUR SYS_REFCURSOR;

LV_EMP_TYPE EMP%ROWTYPE;
LV_DEPT_TYPE DEPT%ROWTYPE;

BEGIN
DBMS_OUTPUT.PUT_LINE('*****************CURSOR1
DETAILS*****************');
OPEN C_REF_CUR FOR SELECT * FROM EMP;
LOOP
FETCH C_REF_CUR INTO LV_EMP_TYPE;
EXIT WHEN C_REF_CUR%NOTFOUND;
DBMS_OUTPUT.PUT_LINE(LV_EMP_TYPE.EMPNO||'-'||
LV_EMP_TYPE.ENAME||'-'||LV_EMP_TYPE.JOB);
END LOOP;
CLOSE C_REF_CUR;
END;
/

You might also like