Previous PageTable Of ContentsNext Page


Using a Cursor (Multiple-Row Operation)

Retrieving Multiple Rows

Declaring a Cursor

Opening a Cursor

Using a Cursor to Retrieve Data

Deleting Data with a Cursor

Updating Data with a Cursor

Closing the Cursor


Using a Cursor (Multiple-Row Operation)

Retrieving Multiple Rows

When a query may return more than one row, the program must execute the query differently. Multiple-row queries are handled in two stages. First, the program starts the query. (No data is returned immediately.) Then, the program requests the rows of data one at a time via a cursor.

A cursor, as used in an application program, is a data selector that can operate on specified rows from the database. The following list is the general sequence for using a cursor.

  1. Declare the cursor and its associated SELECT statement. This merely allocates storage to hold the cursor.
  2. Open the cursor. This starts the execution of the associated SELECT statement. It actually contains three substeps, namely parse the SQL statements, bind the host variables, and begin execution of the statement.
  3. Fetch (or delete, update) a row of data into host variables and process it. Repeat this step until all rows are fetched.
  4. Close the cursor.

These operations are performed with the DECLARE, OPEN, FETCH, and CLOSE statements.

Declaring a Cursor

A new cursor must be declared for each SELECT command within an application program, except for those that retrieve a single row.

The syntax for DECLARE is:

 EXEC SQL DECLARE cursor_name [SCROLL] CURSOR FOR select_statement  
         [INTO :output_host_var :indicator_var [, :output_host_var :indicator_var]] 

The INTO host_variable clause can also be defined in the FETCH statement. If you want to use all available methods of fetching data (i.e., FETCH NEXT, PREVIOUS, LAST, FIRST, ABSOLUTE, and RELATIVE), you must specify SCROLL when declaring a cursor.

If you would like to fetch more than one rows in a single FETCH statement, you must also specify the SCROLL keyword when declaring the cursor.

The following is an example of a SQL command for declaring a cursor:

EXEC SQL DECLARE vendCursor CURSOR FOR  
         SELECT vendorName FROM vendors     
         WHERE vendorNumber = :inputNo;   

Or you can put the INTO clause in the DECLARE statement. In this case, the INTO clause can be omitted in the FETCH statement.

EXEC SQL DECLARE vendCursor CURSOR FOR  
         SELECT vendorName FROM vendors     
         WHERE vendorNumber = :inputNo    
         INTO :vendName;

Opening a Cursor

A cursor must be in an open state to operate on the contents of the specified rows. The OPEN command is followed by the name of the cursor given in the DECLARE command.

The syntax for OPEN is:

EXEC SQL OPEN    cursor_name 
       [USING :input_host_var [:indicator_var] 
           [, :input_host_var [:indicator_var]]] 

The following is an example of an SQL command for opening a cursor:

EXEC SQL OPEN vendCursor; 

When the OPEN command is executed, the cursor finds and points to the first row of the result set that satisfies the search condition. If there are input host variables in the cursor, you must specify the values for all input host variables before or in the OPEN cursor statement. In the above case, because the input host variables have been defined in the DECLARE statement, there's no need to specify the input host variables again in the OPEN cursor statement.

Using a Cursor to Retrieve Data

A cursor retrieves data by using the FETCH command. In a loop, FETCH advances the cursor in the result set and retrieves the current row, copying the values of the columns specified in the SELECT list into the host variables designated by the INTO clause.

The syntax for FETCH is:

EXEC SQL FETCH [NEXT | PREVIOUS | FIRST | LAST | ABSOLUTE nth_position
    | RELATIVE nth_position] [num_rows ROWS] cursor_name  
   [INTO :input_host_var [:indicator_var] 
   [, :input_host_var [:indicator_var], ...]] 

where nth_position and num_rows can be a host variable or a constant integer.

NOTE: PREVIOUS, FIRST, LAST, ABSOLUTE nth_position, RELATIVE nth_position and num_rows ROWS are available only with cursors defined with cursors defined with the SCROLL option.

Command Parameters

NEXT:

Returns the next row within the results set. NEXT is the default cursor fetch.

For example:

EXEC SQL FETCH cur1; /* default is    fetch next */ 
EXEC SQL FETCH NEXT cur1 INTO :c1, :c2;

PREVIOUS:

Returns the previous row within the results set.

For example:

EXEC SQL FETCH PREVIOUS cur1 INTO :c1,    :c2;

FIRST:

Moves the cursor to the first row within the result set and returns the first row.

For example:

EXEC SQL FETCH FIRST cur1 INTO :c1, :c2;

LAST:

Moves the cursor to the last row within the results set and returns the last row.

For example:

EXEC SQL FETCH LAST cur1 INTO :c1, :c2;

ABSOLUTE n:

Returns the nth row within the results set. If n is a negative value, the returned row will be the nth row counting backward from the last row of the results set.

For example:

n = 10; 
EXEC SQL FETCH ABSOLUTE :n cur1 INTO :c1, :c2;

RELATIVE n:

Returns the nth row after the currently fetched row. If n is a negative value, the returned row will be the nth row counting backward from the relative position of the cursor.

For example:

n = 10; 
EXEC SQL FETCH RELATIVE :n cur1 INTO :c1, :c2; 

The following is an example of an SQL command for fetching results from a cursor:

EXEC SQL FETCH vendCursor INTO :vendName; 

You must use a FETCH command for each row to be retrieved.

After all rows in the result set have been retrieved, DBMaker sets the SQLCODE field of SQLCA to the value SQL_NO_DATA_FOUND to indicate that no more rows are found. Indicated variables can be declared with the host variables to detect null values.

FETCH Multiple rows in a FETCH statement:
:num_rows ROW: When you specified this syntax in FETCH statement INTO arrayed host variable, you can retrieve more than one data values in a FETCH statement.

EXEC SQL BEGIN DECLARE SETION;    
int nrows; 
int host1[50]; 
int host2[50]; 
char host3[50][100]; /* 50: means the maximum available fetched data values, 100: means
 the maximum data buffer length of each element. */ 
EXEC SQL END DECLARE SECTION;    
EXEC SQL DECLARE myCur SCROLL CURSOR FOR SELECT c1,c2,c3 FROM table1 INTO :host1, :host2,
 :host3; 
EXEC SQL OPEN myCur; 
nrows = 50; 
/* loop until no data found */    
while (SQLCODE != SQL_NO_DATA_FOUND)    
   {  
    EXEC SQL FETCH :nrows ROWS myCur; /* This will fetch 50 rows into host1, host2, host3,
     because the maximum fetched  */ 
    for (j = 0; j < sqlca.sqlerrd[3]; j++) /* print out according to the number of returned
     rows */ 
    printout(host1, host2, host3);    
   } 
EXEC SQL CLOSE myCur;

Deleting Data with a Cursor

With a cursor, you can select one row at a time to be deleted from a table. Any additional rows must be fetched individually for deletion.

To delete a row, declare the cursor with a SELECT command. Then, use the OPEN and FETCH commands to open the cursor and position it on the row you want to delete. Finally, execute the DELETE command. To delete another row, you must reposition the cursor with another FETCH command.

EXEC SQL DELETE FROM supplier WHERE CURRENT OF vendCursor; 

Do not use the COMMIT WORK command between consecutive deletions. Executing this command implicitly closes the cursor and terminates the deletion process. Working with autocommit mode on will have the same results.

Turn autocommit mode off before using a DELETE or UPDATE WHERE CURRENT OF cursor statement. For information on how to set autocommit mode, please refer to "Transaction processing" in Chapter 5.

Updating Data with a Cursor

You can use a cursor to select one row at a time to update. You must reposition the cursor to update additional rows.

To update a row, declare the cursor with a SELECT command. Use the OPEN and FETCH commands to open the cursor and position it on the row you want to update. Finally, execute the UPDATE command. To update another row, you must reposition the cursor with another FETCH command.

EXEC SQL UPDATE supplier SET price = price + 10 
          WHERE CURRENT OF vendCursor;  

Do not use the COMMIT WORK command between consecutive updates, and make sure autocommit mode is off. Either of these will close the cursor and terminate the update process.

Closing the Cursor

COMMIT WORK and ROLLBACK WORK commands will implicitly close a cursor. You can explicitly close a cursor with the CLOSE CURSOR command. When you no longer need a cursor, you should close it to free any allocated resources.

The syntax for CLOSE CURSOR is:

EXEC SQL CLOSE cursor_name 

The following is an example of an SQL command for closing a cursor:

EXEC SQL CLOSE vendCursor; 

The cursor is dropped and cannot be used (opened or fetched) again.

Previous PageTop Of PageTable Of ContentsNext Page

 

Copyright 2002 SYSCOM Computer Engineering Co. All rights reserved.