Cursors: IF-2213 Pemrograman Basis Data Tahun Ajaran 2012-2013
Cursors: IF-2213 Pemrograman Basis Data Tahun Ajaran 2012-2013
Cursors
1
05/07/20
Cursors
• A major problem in using SQL statements in a programming
language is that a mismatch occurs because SQL operates on
sets of records, whereas languages do not cleanly support a set-
of-records abstraction.
• The solution is to essentially provide a mechanism that allows us
to retrieve rows one at a time from a relation. This mechanism is
called a cursor.
• A cursor provides a subset of data, defined by a query, retrieved
into memory when opened, and stored in memory until the cursor
is closed.
• They are meant to work with SELECT statements that return more
than one record at a time.
2
Cursors
3
05/07/20
05/07/20
Declare the Cursor
CURSOR cursor_name [parameter_list]
[RETURN return_type]
IS query
[FOR UPDATE [OF (column_list)][NOWAIT]];
Example:
• CURSOR movie_cur1 • CURSOR movie_cur1 (i_year IN NUMBER)
IS IS
SELECT year SELECT year
FROM Movie FROM Movie
WHERE year > 1950; WHERE year > i_year;
4
05/07/20
Open the Cursor
OPEN cursor_name [(parameter_values)];
Example:
• OPEN movie_cur1; • OPEN movie_cur1 (1950)
5
05/07/20
Fetch Records from the Cursor
• The FETCH command operates on the current record only and
proceeds through the result set one record at a time.
Example:
• A fetch of a single-column result set into a single variable:
FETCH movie_cur1 INTO v_year;
• A fetch where the cursor returns multiple rows and requires
multiple variables:
FETCH movie_cur INTO v_title, v_year;
The SELECT statement for MOVIE_CUR must include the title
and year columns in that order.
6
05/07/20
Close the Cursor
CLOSE cursor_name;
7
05/07/20
Navigate Cursors Through Loop
• Cursors are most often used with LOOPS to provide a way to
navigate through the active record set.
• Types of loop:
– Simple loop
LOOP ... END LOOP;
• To leave a loop, use EXIT, or EXIT WHEN(...) to exit
conditionally
– While loop
WHILE … LOOP … END LOOP;
– For loop
FOR ….. LOOP …. END LOOP;
• It does not require an explicit OPEN, FETCH, or CLOSE.
• The for-loop uses a variable that is never declared.
8
05/07/20
CREATE OR REPLACE PROCEDURE MovieList (
name Studio.name%TYPE) AS
v_movie Movie%ROWTYPE;
CURSOR movie_cur IS
SELECT * FROM Movie WHERE studioName = name;
BEGIN
OPEN movie_cur;
LOOP
FETCH movie_cur INTO v_movie;
EXIT WHEN movie_cur%NOTFOUND;
DBMS_OUTPUT.PUT_LINE(v_movie.title);
END LOOP;
CLOSE movie_cur;
END MovieList;
9
05/07/20
CREATE OR REPLACE PROCEDURE MovieList (
name Studio.name%TYPE) AS
v_movie Movie%ROWTYPE;
CURSOR movie_cur IS
SELECT * FROM Movie WHERE studioName = name;
BEGIN
OPEN movie_cur;
FETCH movie_cur INTO v_movie;
WHILE movie_cur%FOUND LOOP
DBMS_OUTPUT.PUT_LINE(v_movie.title);
FETCH movie_cur INTO v_movie;
END LOOP;
CLOSE movie_cur;
END MovieList;
10
05/07/20
CREATE OR REPLACE PROCEDURE MovieList (
name Studio.name%TYPE) AS
CURSOR movie_cur IS
SELECT * FROM Movie WHERE studioName = name;
BEGIN
FOR v_movie IN movie_cur LOOP
DBMS_OUTPUT.PUT_LINE(v_movie.title);
END LOOP;
END MovieList;
11
05/07/20
Navigate Cursors Through Loop
SQL> CALL MovieList ('Paramount Pictures');
The Godfather
The Godfather: Part II
Forrest Gump
Call completed.
12
05/07/20
Cursor Attributes
• %FOUND The %FOUND attribute tests whether a FETCH
returned a record. The return value is of Boolean
type. If TRUE, a row was returned by the FETCH. If
FALSE, a row was not returned.
• %ISOPEN This attribute tests to see if a cursor is already open.
If TRUE, the cursor is open. If FALSE, it is not open.
• %NOTFOUND %NOTFOUND is the opposite of %FOUND.
It returns TRUE if a row was not returned by the
FETCH and FALSE if one was returned.
• %ROWCOUNT This tests for the number of rows fetched
from the cursor at any given time and returns a
number.
13
05/07/20
CREATE OR REPLACE PROCEDURE MovieList (
name Studio.name%TYPE) AS
v_movie Movie%ROWTYPE;
v_row_count INTEGER := 0;
CURSOR movie_cur IS
SELECT * FROM Movie WHERE studioName = name;
14
05/07/20
BEGIN
OPEN movie_cur;
LOOP
FETCH movie_cur INTO v_movie;
EXIT WHEN movie_cur%NOTFOUND;
–– Alternatively use EXIT WHEN NOT movie_cur%FOUND;
DBMS_OUTPUT.PUT_LINE(v_movie.title);
END LOOP;
v_row_count := movie_cur%ROWCOUNT;
DBMS_OUTPUT.PUT_LINE(name||' produces '||v_row_count||' movie(s).
CLOSE movie_cur;
IF movie_cur%ISOPEN = FALSE THEN
DBMS_OUTPUT.PUT_LINE('Cursor closed');
ELSE
DBMS_OUTPUT.PUT_LINE('The cursor is still open');
END IF;
END MovieList;
15
05/07/20
Cursor Attributes
SQL> CALL MovieList('Paramount Pictures');
The Godfather
The Godfather: Part II
Forrest Gump
Paramount Pictures produces 3 movie(s).
Cursor closed
Call completed.
16