Cursors in PL-SQL

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

Cursors in PL/SQL:

Oracle creates a memory area, known as the context area, for processing an SQL statement,
which contains all the information needed for processing the statement; for example, the
number of rows processed, etc.
A cursor is a pointer to this context area. PL/SQL controls the context area through a cursor. A
cursor holds the rows (one or more) returned by a SQL statement. The set of rows the cursor
holds is referred to as the active set.
You can name a cursor so that it could be referred to in a program to fetch and process the rows
returned by the SQL statement, one at a time.
There are two types of cursors − implicit cursors and explicit cursors.
Implicit cursors

Whenever Oracle executes an SQL statement such as SELECT INTO, INSERT, UPDATE,
and DELETE, it automatically creates an implicit cursor.
These cursors cannot be named and, hence they cannot be controlled or referred from another
place of the code. We can refer only to the most recent cursor through the cursor attributes.

Both Implicit cursor and the explicit cursor has certain attributes that can be accessed. These
attributes give more information about the cursor operations. Below are the different cursor
attributes and their usage.

The following table provides the description of the most used attributes −

S.No Attribute & Description

%FOUND
1 Returns TRUE if an INSERT, UPDATE, or DELETE statement affected one or
more rows or a SELECT INTO statement returned one or more rows. Otherwise, it
returns FALSE.

%NOTFOUND
2 The logical opposite of %FOUND. It returns TRUE if an INSERT, UPDATE, or
DELETE statement affected no rows, or a SELECT INTO statement returned no
rows. Otherwise, it returns FALSE.

%ISOPEN
3 Always returns FALSE for implicit cursors, because Oracle closes the SQL cursor
automatically after executing its associated SQL statement.

%ROWCOUNT
4 Returns the number of rows affected by an INSERT, UPDATE, or DELETE
statement, or returned by a SELECT INTO statement.
Any SQL cursor attribute will be accessed as sql%attribute_name as shown below in the
example.
Example
We will be using the CUSTOMERS table we had created and used in the previous chapters.
Select * from customers;

+----+----------+-----+-----------+----------+
| ID | NAME | AGE | ADDRESS | SALARY |
+----+----------+-----+-----------+----------+
| 1 | Ramesh | 32 | Ahmedabad | 2000.00 |
| 2 | Khilan | 25 | Delhi | 1500.00 |
| 3 | kaushik | 23 | Kota | 2000.00 |
| 4 | Chaitali | 25 | Mumbai | 6500.00 |
| 5 | Hardik | 27 | Bhopal | 8500.00 |
| 6 | Komal | 22 | MP | 4500.00 |
+----+----------+-----+-----------+----------+
The following program will update the table and increase the salary of each customer by 500
and use the SQL%ROWCOUNT attribute to determine the number of rows affected −
DECLARE
total_rows number(2);

BEGIN

UPDATE customers
SET salary = salary + 500;

IF sql%notfound THEN
dbms_output.put_line('no customers selected');
ELSIF sql%found THEN
total_rows := sql%rowcount;
dbms_output.put_line( total_rows || ' customers selected ');
END IF;
OR
IF sql%found THEN
total_rows := sql%rowcount;
dbms_output.put_line( total_rows || ' Records Update ');
ELSIF
dbms_output.put_line('no customers selected');
END IF;

END;
/
When the above code is executed at the SQL prompt, it produces the following result −
6 customers selected
PL/SQL procedure successfully completed.

Update Salary of first five customers:

DECLARE
total_rows number(2);

BEGIN

UPDATE customers
SET salary = salary + 500
where ID Between 1 and 5;

OR

UPDATE customers
SET salary = salary + 500
where ID <=5;

IF sql%notfound THEN
dbms_output.put_line('no customers selected');
ELSIF sql%found THEN
total_rows := sql%rowcount;
dbms_output.put_line( total_rows || ' customers selected ');
END IF;
OR
IF sql%found THEN
total_rows := sql%rowcount;
dbms_output.put_line( total_rows || ' Records Update ');
ELSIF
dbms_output.put_line('no customers selected');
END IF;

END;
/
If you check the records in customers table, you will find that the rows have been updated −
Select * from customers;

+----+----------+-----+-----------+----------+
| ID | NAME | AGE | ADDRESS | SALARY |
+----+----------+-----+-----------+----------+
| 1 | Ramesh | 32 | Ahmedabad | 2500.00 |
| 2 | Khilan | 25 | Delhi | 2000.00 |
| 3 | kaushik | 23 | Kota | 2500.00 |
| 4 | Chaitali | 25 | Mumbai | 7000.00 |
| 5 | Hardik | 27 | Bhopal | 9000.00 |
| 6 | Komal | 22 | MP | 5000.00 |
+----+----------+-----+-----------+----------+

Explicit Cursors

Explicit cursors are programmer-defined cursors for gaining more control over the context
area. An explicit cursor should be defined in the declaration section of the PL/SQL Block. It is
created on a SELECT Statement which returns more than one row.
Working with an explicit cursor includes the following steps −
 Declaring the cursor for initializing the memory
 Opening the cursor for allocating the memory
 Fetching the cursor for retrieving the data
 Closing the cursor to release the allocated memory

 Declaring the cursor


Declaring the cursor simply means to create one named context area for the 'SELECT'
statement that is defined in the declaration part. The name of this context area is same as
the cursor name.

 Opening Cursor
Opening the cursor will instruct the PL/SQL to allocate the memory for this cursor. It will
make the cursor ready to fetch the records.

 Fetching Data from the Cursor


In this process, the 'SELECT' statement is executed and the rows fetched are stored in the
allocated memory. These are now called as active sets. Fetching data from the cursor is a
record-level activity that means we can access the data in a record-by-record way.

Each fetch statement will fetch one active set and holds the information of that particular
record. This statement is same as 'SELECT' statement that fetches the record and assigns
to the variable in the 'INTO' clause, but it will not throw any exceptions.

 Closing the Cursor


Once all the record is fetched now, we need to close the cursor so that the memory
allocated to this context area will be released.
Syntax :

DECLARE

CURSOR <cursor_name> IS <SELECT statement>

<cursor_variable declaration>

BEGIN

OPEN <cursor_name>;

FETCH <cursor_name> INTO <cursor_variable>;


.
.
CLOSE <cursor_name>;

END;

 In the above syntax, the declaration part contains the declaration of the cursor and the
cursor variable in which the fetched data will be assigned.
 The cursor is created for the 'SELECT' statement that is given in the cursor declaration.
 In execution part, the declared cursor is opened, fetched and closed.

Example :

Declaring the Cursor

Declaring the cursor defines the cursor with a name and the associated SELECT statement. For
example −
CURSOR c_customers IS
SELECT id, name, address FROM customers;

Opening the Cursor

Opening the cursor allocates the memory for the cursor and makes it ready for fetching the rows
returned by the SQL statement into it. For example, we will open the above defined cursor as
follows −
OPEN c_customers;

Fetching the Cursor

Fetching the cursor involves accessing one row at a time. For example, we will fetch rows from
the above-opened cursor as follows −
FETCH c_customers INTO c_id, c_name, c_addr;
Closing the Cursor

Closing the cursor means releasing the allocated memory. For example, we will close the
above-opened cursor as follows −
CLOSE c_customers;

Following is a complete example to illustrate the concepts of explicit cursors:


Example : Display All the Records of Customer Table:
DECLARE

c_id customers.id%type;
c_name customers.name%type;
c_addr customers.address%type;

CURSOR c_customers IS ‘Cursor Declaration


SELECT id, name, address FROM customers;

BEGIN

OPEN c_customers; ‘Cursor Opened

LOOP

FETCH c_customers into c_id, c_name, c_addr; ‘Fetching the data from Cursor

EXIT WHEN c_customers%notfound;

dbms_output.put_line(c_id || ' ' || c_name || ' ' || c_addr);

END LOOP;

CLOSE c_customers; ‘Closing the Cursor

END;
/
Display Records from Wholesaler Table Using Cursor :

Wholesaler(w_no, w_name, address, city)

DECLARE

wno wholesaler.w_no%type;
wname wholesaler.w_name%type;
wadd wholesaler.address%type;
wcity wholesaler.city%type;

CURSOR c_wholesaler IS ‘Declare Cursor


SELECT w_no, w_name, address, city FROM wholesaler;

BEGIN

OPEN c_wholesaler; ‘Open Cursor

LOOP

FETCH c_wholesaler into wno, wname, wadd, wcity; ‘Fetching Data from Cursor

EXIT WHEN c_wholesaler%notfound;

dbms_output.put_line(wno || ' ' || wname || ' ' || wadd|| ' ' || wcity);

END LOOP;

CLOSE c_wholesaler; ‘Close Cursor

END;

w1 sumit pune Pune

w2 ganesh pimpri Pune

PL/SQL procedure successfully completed.


PL/SQL Cursor with Parameters

An explicit cursor may accept a list of parameters. Each time you open the cursor, you can pass
different arguments to the cursor, which results in different result sets.

Example :

Consider Table : Emp(eid, ename, esal)

Cursor display employee information from emp_information table whose eid is four (4).

DECLARE
cursor c(no number) is select * from emp ‘Declaring Cursor
where eid = no;
temp emp%rowtype;
BEGIN
OPEN c(4); ‘Open the Cursor
LOOP
FETCH c INTO temp; ‘Fetch Data from Cursor
EXIT WHEN c%NOTFOUND;

dbms_output.put_line('EMP_No: '||temp.eid);
dbms_output.put_line('EMP_Name: '||temp.ename);
dbms_output.put_line('EMP_Salary:'||temp.esal);
END LOOP;
/*OR Use the following LOOP
FOR temp IN c(4) LOOP
dbms_output.put_line('EMP_No: '||temp.eid);
dbms_output.put_line('EMP_Name: '||temp.ename);
dbms_output.put_line('EMP_Salary:'||temp.esal);
END Loop;*/
CLOSE c; ‘Close the Cursor
END;
/

Cursor to Display records of employee of first four highest paid employees :


Cursor to Display records of employee of first four highest paid employees :

DECLARE

cursor c1 is select * from emp order by sal desc;

erec emp%rowtype;

BEGIN

OPEN c1;

LOOP

FETCH c1 into erec.eno, erec.name, erec.sal;

exit when c1%notfound;

IF c1%rowcount<=4 THEN

dbms_output.put_line(erec.eno ||' '|| erec.name||' '|| erec.sal);

END IF;

END LOOP;

END;

Output :

4 aparna 50000

5 vishal 45000

1 sumit 20000

3 akash 14000
Create a procedure to Display records of employee of first four highest paid employees :

create or replace procedure emppro

as

cursor c1 is select * from emp order by sal desc;

erec emp%rowtype;

BEGIN

OPEN c1;

LOOP

FETCH c1 into erec.eno, erec.name, erec.sal;

exit when c1%notfound;

IF c1%rowcount<=4 THEN

dbms_output.put_line(erec.eno ||' '|| erec.name||' '|| erec.sal);

END IF;

END LOOP;

END;

Procedure created.

Execute the procedure empro :

SQL> execute emppro;

4 aparna 50000

5 vishal 45000

1 sumit 20000

3 akash 14000

PL/SQL procedure successfully completed.

You might also like