Oracle Cursors
By Nagaraju Byri
Cursors:
A cursor is a temporary work area (known as context area) created in the system memory when a SQL statement is
executed. A cursor contains information on a select statement and the rows of data accessed by it.
This temporary work area is used to store the data retrieved from the database, and manipulate this data. A
cursor can hold more than one row, but can process only one row at a time. The set of rows the cursor holds is
called the active set.
There are two types of cursors:
Implicit cursors - (predefined cursors / Internal cursors/System defined cursors.)
Explicit cursors - (User-Defined Cursors / external cursors)
Implicit Cursors:
Implicit cursors are automatically created by Oracle whenever an SQL statement is executed, when there is no explicit cursor for
the statement. Programmers cannot control the implicit cursors and the information in it.
Whenever a DML statement (INSERT, UPDATE and DELETE) is issued, an implicit cursor is associated with this statement. For
INSERT operations, the cursor holds the data that needs to be inserted. For UPDATE and DELETE operations, the cursor identifies
the rows that would be affected.
In PL/SQL, you can refer to the most recent implicit cursor as the SQL cursor, which always has the attributes like %FOUND,
%ISOPEN, %NOTFOUND, and %ROWCOUNT. The SQL cursor has additional attributes, %BULK_ROWCOUNT and %BULK_EXCEPTIONS,
designed for use with the FORALL statement. The following table provides the description of the most used attributes:
Attribute
Description
%FOUND
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
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
Always returns FALSE for implicit cursors, because Oracle closes the SQL cursor automatically after
executing its associated SQL statement.
%ROWCOUNT
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;
The following program would update the table and increase 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;
END;
/
When the above code is executed at SQL prompt, it produces the following result:
6 customers selected
PL/SQL procedure successfully completed.
If you check the records in customers table, you will find that the rows have been updated:
Select * from customers;
Page 1 of 5
Oracle Cursors
By Nagaraju Byri
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.
The syntax for creating an explicit cursor is :
CURSOR cursor_name IS
select_statement;
Working with an explicit cursor involves four steps:
1.
2.
3.
4.
Declaring the cursor for initializing in the memory
Opening the cursor for allocating memory
Fetching the cursor for retrieving data
Closing the cursor to release allocated memory
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 memory for the cursor and makes it ready for fetching the rows returned by
the SQL statement into it. For example, we will open 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 aboveopened 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 above-opened
cursor as follows:
CLOSE c_customers;
Example:
Following is a complete example to illustrate the concepts of explicit cursors:
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;
/
PL/SQL procedure successfully completed.
Example 2:
DECLARE
emp_rec emp%rowtype;
CURSOR emp_cur IS
SELECT * FROM emp WHERE salary > 1500;
BEGIN
OPEN emp_cur;
FETCH emp_cur INTO emp_rec;
dbms_output.put_line (emp_rec.empno || ' ' || emp_rec.ename||' '||emp_rec.job);
CLOSE emp_cur;
END;
Page 2 of 5
Oracle Cursors
By Nagaraju Byri
Explicit Cursor Attributes?
Oracle provides some attributes known as Explicit Cursor Attributes to control the data processing while using
cursors. We use these attributes to avoid errors while accessing cursors through OPEN, FETCH and CLOSE
Statements.
When does an error occur while accessing an explicit cursor?
a) When we try to open a cursor which is not closed in the previous operation.
b) When we try to fetch a cursor after the last operation.
These are the attributes available to check the status of an explicit cursor.
Attributes
Return values
Example
%FOUND
TRUE, if fetch statement returns at least one row.
Cursor_name%FOUND
FALSE, if fetch statement doesnt return a row.
%NOTFOUND
TRUE, , if fetch statement doesnt return a row.
Cursor_name%NOTFOUND
FALSE, if fetch statement returns at least one row.
%ROWCOUNT
The number of rows fetched by the fetch statement
Cursor_name%ROWCOUNT
If no row is returned, the PL/SQL statement returns an
error.
%ISOPEN
TRUE, if the cursor is already open in the program
Cursor_name%ISNAME
FALSE, if the cursor is not opened in the program.
Using Loops with Explicit Cursors:
Oracle provides three types of cursors namely SIMPLE LOOP, WHILE LOOP and FOR LOOP. These loops can be used to process
multiple rows in the cursor. Here I will modify the same example for each loops to explain how to use loops with cursors.
Cursor with a Simple Loop:
DECLARE
CURSOR emp_cur IS
SELECT empno, ename, sal FROM emp;
emp_rec emp_cur%rowtype;
BEGIN
OPEN emp_cur;
LOOP
FETCH emp_cur INTO emp_rec;
EXIT WHEN emp_cur%NOTFOUND;
dbms_output.put_line(emp_cur.empno|| ' ' ||emp_cur.ename|| ' ' ||emp_cur.sal);
END LOOP;
CLOSE emp_cur;
END;
/
In the above example we are using two cursor attributes %ISOPEN and %NOTFOUND.
Cursor with a While Loop:
Lets modify the above program to use while loop.
DECLARE
CURSOR emp_cur IS
SELECT empno, ename, sal FROM emp_tbl;
emp_rec emp_cur%rowtype;
BEGIN
OPEN emp_cur;
FETCH emp_cur INTO emp_rec;
WHILE emp_cur%FOUND THEN
LOOP
dbms_output.put_line(emp_cur.empno || ' ' ||emp_cur.ename|| ' ' ||emp_cur.sal);
FETCH emp_cur INTO emp_rec;
END LOOP;
END;
/
Cursor with a FOR Loop:
Page 3 of 5
Oracle Cursors
By Nagaraju Byri
When using FOR LOOP you need not declare a record or variables to store the cursor values, need not open, fetch and close the
cursor. These functions are accomplished by the FOR LOOP automatically.
General Syntax for using FOR LOOP:
FOR record_name IN cusror_name
LOOP
process the row...
END LOOP;
Lets use the above example to learn how to use for loops in cursors.
DECLARE
CURSOR emp_cur IS
SELECT empno,ename,sal FROM emp;
emp_rec emp_cur%rowtype;
BEGIN
FOR emp_rec in emp_cur
LOOP
dbms_output.put_line(emp_cur.empno || ' ' ||emp_cur.ename || ' ' ||emp_cur.sal);
END LOOP;
END;
/
Parameterized Cursors: When opening a cursor we can pass something value to the cursor those values will be used within
cursor is called parameterized cursor.
Syntax:
Open <cursor_name>(parameter);
Example1:
CREATEORREPLACEPROCEDUREAPPS.ZEBA_CUR1IS
CURSOREMP_CUR(p_deptnoNUMBER)IS
SELECT*fromempwheredeptno=p_deptno;
v_empcur_rowEMP_CUR%ROWTYPE;
BEGIN
OPENEMP_CUR(20);
LOOP
FETCHEMP_CURINTOV_EMPCUR_ROW;
EXITWHENEMP_CUR%NOTFOUND;
DBMS_OUTPUT.PUT_LINE(v_empcur_row.empno||''||v_empcur_row.ENAME||''||
v_empcur_row.SAL);
ENDLOOP;
CLOSEEMP_CUR;
END;
Example 2:
CREATEORREPLACEPROCEDUREAPPS.ZEBA_CUR1IS
CURSOREMP_CUR(p_deptnoNUMBER)IS
SELECT*fromempwheredeptno=p_deptno;
CURSORDEPT_CURIS
select*fromdept;
v_empcur_rowEMP_CUR%ROWTYPE;
v_deptcur_rowDEPT_CUR%ROWTYPE;
BEGIN
OPENDEPT_CUR;
LOOP
FETCHDEPT_CURINTOv_deptcur_row;
EXITWHENDEPT_CUR%NOTFOUND;
DBMS_OUTPUT.PUT_LINE('****************************************************');
DBMS_OUTPUT.PUT_LINE(v_deptcur_row.deptno||'DepartmentDetails');
DBMS_OUTPUT.PUT_LINE('****************************************************');
OPENEMP_CUR(v_deptcur_row.deptno);
LOOP
FETCHEMP_CURINTOV_EMPCUR_ROW;
EXITWHENEMP_CUR%NOTFOUND;
DBMS_OUTPUT.PUT_LINE(v_empcur_row.empno||''||v_empcur_row.ENAME||''||
v_empcur_row.SAL);
ENDLOOP;
CLOSEEMP_CUR;
ENDLOOP;
Page 4 of 5
Oracle Cursors
By Nagaraju Byri
CLOSEDEPT_CUR;
END;
Page 5 of 5