When you declare a cursor, you name it and associate it with a specific query using the syntax
CURSOR cursor_name [(parameter[, parameter]...)] [RETURN return_type] IS select_statement;
where return_type must represent a record or a row in
a database table, and parameter stands for the following syntax:
cursor_parameter_name [IN] datatype [{:= | DEFAULT} expression]
For example, you might declare cursors named c1 and c2,
as follows:
DECLARE
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;
Opening the cursor executes the query and identifies the result
set, which consists of all rows that meet the query search criteria. For cursors
declared using the FOR UPDATE clause, the OPEN
statement also locks those rows. An example of the OPEN statement
follows:
DECLARE CURSOR c1 IS SELECT ename, job FROM emp WHERE sal < 3000; ... BEGIN OPEN c1; ... END;
Rows in the result set are not retrieved when the OPEN
statement is executed. Rather, the FETCH statement retrieves the
rows.
the FETCH statement retrieves the rows in the result
set one at a time. After each fetch, the cursor advances to the next row in the
result set. An example follows:
FETCH c1 INTO my_empno, my_ename, my_deptno;
For each column value returned by the query associated with the
cursor, there must be a corresponding, type-compatible variable in the INTO
list. Typically, you use the FETCH statement in the following way:
LOOP FETCH c1 INTO my_record; EXIT WHEN c1%NOTFOUND; -- process data record END LOOP;
The query can reference PL/SQL variables within its scope.
However, any variables in the query are evaluated only when the cursor is
opened. In the following example, each retrieved salary is multiplied by 2,
even though factor is incremented after every fetch:
DECLARE
my_sal emp.sal%TYPE;
my_job emp.job%TYPE;
factor INTEGER := 2;
CURSOR c1 IS SELECT factor*sal FROM emp WHERE job = my_job;
BEGIN
...
OPEN c1; -- here factor equals 2
LOOP
FETCH c1 INTO my_sal;
EXIT WHEN c1%NOTFOUND;
factor := factor + 1; -- does not affect FETCH
END LOOP;
END;
The CLOSE statement disables the cursor, and the
result set becomes undefined. Once a cursor is closed, you can reopen it. Any
other operation on a closed cursor raises the predefined exception INVALID_CURSOR.