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

Cursors

Every SQL statement executed by the Oracle server


has an associated individual cursor:
• Implicit cursors: Declared and managed by
Using Explicit Cursors PL/SQL for all DML and PL/SQL SELECT
statements
• Explicit cursors: Declared and managed by the
programmer

Copyright © 2006, Oracle. All rights reserved. 7-3 Copyright © 2006, Oracle. All rights reserved.

Objectives Explicit Cursor Operations

After completing this lesson, you should be able to do


the following: Table
• Distinguish between implicit and explicit cursors 100 King AD_PRES
• Discuss the reasons for using explicit cursors 101 Kochhar AD_VP
Active set
• Declare and control explicit cursors 102 De Haan AD_VP
• Use simple loops and cursor FOR loops to fetch . . .
data . . .
• Declare and use cursors with parameters . . .
• Lock rows with the FOR UPDATE clause 139 Seo ST_CLERK
• Reference the current row with the WHERE CURRENT 140 Patel ST_CLERK
clause . . .

7-2 Copyright © 2006, Oracle. All rights reserved. 7-4 Copyright © 2006, Oracle. All rights reserved.

1
Controlling Explicit Cursors Declaring the Cursor

Syntax:
No
CURSOR cursor_name IS
select_statement;
Yes
DECLARE OPEN FETCH EMPTY? CLOSE
Examples
DECLARE
• Create a • Identify the • Load the • Test for • Release the CURSOR emp_cursor IS
named active set. current existing active set. SELECT employee_id, last_name FROM employees
SQL area. row into rows. WHERE department_id =30;
variables.
• Return to DECLARE
FETCH if locid NUMBER:= 1700;
rows are CURSOR dept_cursor IS
found. SELECT * FROM departments
WHERE location_id = locid;
...

7-5 Copyright © 2006, Oracle. All rights reserved. 7-7 Copyright © 2006, Oracle. All rights reserved.

Controlling Explicit Cursors

1 Open the cursor.


Cursor
pointer

2 Fetch a row.
Cursor
pointer

Cursor
3 Close the cursor. pointer

7-6 Copyright © 2006, Oracle. All rights reserved. 7-8 Copyright © 2006, Oracle. All rights reserved.

2
Opening the Cursor

DECLARE
CURSOR emp_cursor IS
SELECT employee_id, last_name FROM employees
WHERE department_id =30;
...
BEGIN
OPEN emp_cursor;

7-9 Copyright © 2006, Oracle. All rights reserved. 7-11 Copyright © 2006, Oracle. All rights reserved.

Fetching Data from the Cursor Fetching Data from the Cursor

SET SERVEROUTPUT ON
DECLARE
CURSOR emp_cursor IS
SET SERVEROUTPUT ON
SELECT employee_id, last_name FROM employees
DECLARE
WHERE department_id =30;
CURSOR emp_cursor IS
empno employees.employee_id%TYPE;
SELECT employee_id, last_name FROM employees
lname employees.last_name%TYPE;
WHERE department_id =30;
BEGIN
empno employees.employee_id%TYPE;
OPEN emp_cursor;
lname employees.last_name%TYPE;
LOOP
BEGIN
FETCH emp_cursor INTO empno, lname;
OPEN emp_cursor;
EXIT WHEN emp_cursor%NOTFOUND;
FETCH emp_cursor INTO empno, lname;
DBMS_OUTPUT.PUT_LINE( empno ||' '||lname);
DBMS_OUTPUT.PUT_LINE( empno ||' '||lname);
END LOOP;
...
...
END;
END;
/
/

7-10 Copyright © 2006, Oracle. All rights reserved. 7-12 Copyright © 2006, Oracle. All rights reserved.

3
Closing the Cursor Cursor FOR Loops

Syntax:
... FOR record_name IN cursor_name LOOP
LOOP
statement1;
FETCH emp_cursor INTO empno, lname;
EXIT WHEN emp_cursor%NOTFOUND; statement2;
DBMS_OUTPUT.PUT_LINE( empno ||' '||lname); . . .
END LOOP; END LOOP;
CLOSE emp_cursor;
END;
• The cursor FOR loop is a shortcut to process
/
explicit cursors.
• Implicit open, fetch, exit, and close occur.
• The record is implicitly declared.

7-13 Copyright © 2006, Oracle. All rights reserved. 7-15 Copyright © 2006, Oracle. All rights reserved.

Cursors and Records Cursor FOR Loops

Process the rows of the active set by fetching values


into a PL/SQL record. SET SERVEROUTPUT ON
DECLARE DECLARE
CURSOR emp_cursor IS CURSOR emp_cursor IS
SELECT employee_id, last_name FROM employees
SELECT employee_id, last_name FROM employees
WHERE department_id =30;
WHERE department_id =30;
BEGIN
emp_record emp_cursor%ROWTYPE;
FOR emp_record IN emp_cursor
BEGIN
LOOP
OPEN emp_cursor;
DBMS_OUTPUT.PUT_LINE( emp_record.employee_id
LOOP
||' ' ||emp_record.last_name);
FETCH emp_cursor INTO emp_record;
END LOOP;
...
END;
/

7-14 Copyright © 2006, Oracle. All rights reserved. 7-16 Copyright © 2006, Oracle. All rights reserved.

4
Explicit Cursor Attributes %ROWCOUNT and %NOTFOUND: Example

SET SERVEROUTPUT ON
DECLARE
Obtain status information about a cursor. empno employees.employee_id%TYPE;
Attribute Type Description ename employees.last_name%TYPE;
CURSOR emp_cursor IS SELECT employee_id,
%ISOPEN Boolean Evaluates to TRUE if the cursor is last_name FROM employees;
open BEGIN
OPEN emp_cursor;
%NOTFOUND Boolean Evaluates to TRUE if the most recent LOOP
fetch does not return a row FETCH emp_cursor INTO empno, ename;
EXIT WHEN emp_cursor%ROWCOUNT > 10 OR
%FOUND Boolean Evaluates to TRUE if the most recent emp_cursor%NOTFOUND;
fetch returns a row; complement of DBMS_OUTPUT.PUT_LINE(TO_CHAR(empno)
%NOTFOUND ||' '|| ename);
%ROWCOUNT Number Evaluates to the total number of END LOOP;
rows returned so far CLOSE emp_cursor;
END ;
/

7-17 Copyright © 2006, Oracle. All rights reserved. 7-19 Copyright © 2006, Oracle. All rights reserved.

%ISOPEN Attribute Cursor FOR Loops Using Subqueries

• Fetch rows only when the cursor is open. There is no need to declare the cursor.
• Use the %ISOPEN cursor attribute before
Example
performing a fetch to test whether the cursor is
open. SET SERVEROUTPUT ON
BEGIN
Example FOR emp_record IN (SELECT employee_id, last_name
FROM employees WHERE department_id =30)
IF NOT emp_cursor%ISOPEN THEN LOOP
OPEN emp_cursor; DBMS_OUTPUT.PUT_LINE( emp_record.employee_id ||'
'||emp_record.last_name);
END IF;
END LOOP;
LOOP
END;
FETCH emp_cursor... /

7-18 Copyright © 2006, Oracle. All rights reserved. 7-20 Copyright © 2006, Oracle. All rights reserved.

5
Cursors with Parameters FOR UPDATE Clause

Syntax: Syntax:
CURSOR cursor_name SELECT ...
[(parameter_name datatype, ...)] FROM ...
IS FOR UPDATE [OF column_reference][NOWAIT | WAIT n];
select_statement;
• Use explicit locking to deny access to other
• Pass parameter values to a cursor when the sessions for the duration of a transaction.
cursor is opened and the query is executed. • Lock the rows before the update or delete.
• Open an explicit cursor several times with a
different active set each time.
OPEN cursor_name(parameter_value,.....) ;

7-21 Copyright © 2006, Oracle. All rights reserved. 7-23 Copyright © 2006, Oracle. All rights reserved.

Cursors with Parameters

SET SERVEROUTPUT ON
DECLARE
CURSOR emp_cursor (deptno NUMBER) IS
SELECT employee_id, last_name
FROM employees
WHERE department_id = deptno;
dept_id NUMBER;
lname VARCHAR2(15);
BEGIN
OPEN emp_cursor (10);
...
CLOSE emp_cursor;
OPEN emp_cursor (20);
...

7-22 Copyright © 2006, Oracle. All rights reserved. 7-24 Copyright © 2006, Oracle. All rights reserved.

6
WHERE CURRENT OF Clause Summary

In this lesson, you should have learned how to:


Syntax: • Distinguish cursor types:
WHERE CURRENT OF cursor ;
– Implicit cursors are used for all DML statements
• Use cursors to update or delete the current row. and single-row queries.
• Include the FOR UPDATE clause in the cursor query – Explicit cursors are used for queries of zero,
to lock the rows first. one, or more rows.
• Use the WHERE CURRENT OF clause to reference the • Create and handle explicit cursors
current row from an explicit cursor. • Use simple loops and cursor FOR loops to handle
multiple rows in the cursors
UPDATE employees
SET salary = ... • Evaluate the cursor status by using the cursor
WHERE CURRENT OF emp_cursor; attributes
• Use the FOR UPDATE and WHERE CURRENT OF
clauses to update or delete the current fetched
row
7-25 Copyright © 2006, Oracle. All rights reserved. 7-27 Copyright © 2006, Oracle. All rights reserved.

Cursors with Subqueries Practice 7: Overview

Example This practice covers the following topics:


DECLARE
• Declaring and using explicit cursors to query rows
CURSOR my_cursor IS
SELECT t1.department_id, t1.department_name,
of a table
t2.staff • Using a cursor FOR loop
FROM departments t1, (SELECT department_id, • Applying cursor attributes to test the cursor status
COUNT(*) AS staff
FROM employees • Declaring and using cursors with parameters
GROUP BY department_id) t2 • Using the FOR UPDATE and WHERE CURRENT OF
WHERE t1.department_id = t2.department_id clauses
AND t2.staff >= 3;
...

7-26 Copyright © 2006, Oracle. All rights reserved. 7-28 Copyright © 2006, Oracle. All rights reserved.

7
7-29 Copyright © 2006, Oracle. All rights reserved. 7-31 Copyright © 2006, Oracle. All rights reserved.

7-30 Copyright © 2006, Oracle. All rights reserved. 7-32 Copyright © 2006, Oracle. All rights reserved.

8
7-33 Copyright © 2006, Oracle. All rights reserved.

7-34 Copyright © 2006, Oracle. All rights reserved.

You might also like