DECLARE CURSOR

The DECLARE CURSOR statement defines a cursor.

Invocation

This statement can only be embedded in an application program. It is not an executable statement. It must not be specified in Java.

Authorization

For each table or view identified in the SELECT statement of the cursor, the privilege set must include at least one of the following:

  • The SELECT privilege
  • Ownership of the object
  • DBADM authority for the corresponding database (tables only)
  • SYSADM authority
  • SYSCTRL authority (catalog tables only)
  • Start of changeDATAACCESS authorityEnd of change

If the select-statement contains an SQL data change statement, the authorization requirements of that statement also apply to the DECLARE CURSOR statement.

The SELECT statement of the cursor is one of the following:

  • The prepared select statement identified by statement-name
  • The specified select-statement

If statement-name is specified:

  • The privilege set is determined by the DYNAMICRULES behavior in effect (run, bind, define, or invoke) and is summarized in Table 1. (For more information on these behaviors, including a list of the DYNAMICRULES bind option values that determine them, see Authorization IDs and dynamic SQL.)
  • The authorization check is performed when the SELECT statement is prepared.
  • The cursor cannot be opened unless the SELECT statement is successfully prepared.

If select-statement is specified:

  • The privilege set consists of the privileges that are held by the authorization ID of the owner of the plan or package.
  • If the plan or package is bound with VALIDATE(BIND), the authorization check is performed at bind time, and the bind is unsuccessful if any required privilege does not exist.
  • If the plan or package is bound with VALIDATE(RUN), an authorization check is performed at bind time, but all required privileges need not exist at that time. If all privileges exist at bind time, no authorization checking is performed when the cursor is opened. If any privilege does not exist at bind time, an authorization check is performed the first time the cursor is opened within a unit of work. The OPEN is unsuccessful if any required privilege does not exist.

Syntax

Read syntax diagram
                         .-NO SCROLL------------------------.   
>>-DECLARE--cursor-name--+----------------------------------+--->
                         | .-ASENSITIVE------------.        |   
                         '-+-----------------------+-SCROLL-'   
                           +-INSENSITIVE-----------+            
                           |           .-DYNAMIC-. |            
                           '-SENSITIVE-+---------+-'            
                                       '-STATIC--'              

           .-----------------------------.   
           V  (1)                        |   
>--CURSOR---------+--------------------+-+---------------------->
                  +-holdability--------+     
                  +-returnability------+     
                  '-rowset-positioning-'     

>--FOR--+-select-statement-+-----------------------------------><
        '-statement-name---'   

Notes:
  1. The same clause must not be specified more than once.

holdability:

Read syntax diagram
   .-WITHOUT HOLD-.   
>>-+--------------+--------------------------------------------><
   '-WITH HOLD----'   

returnability:

Read syntax diagram
   .-WITHOUT RETURN-------------.   
>>-+----------------------------+------------------------------><
   |              .-TO CALLER-. |   
   '-WITH RETURN--+-----------+-'   
                  '-TO CLIENT-'     

rowset-positioning:

Read syntax diagram
   .-WITHOUT ROWSET POSITIONING-.   
>>-+----------------------------+------------------------------><
   '-WITH ROWSET POSITIONING----'   

Description

cursor-name
Names the cursor. The name must not identify a cursor that has already been declared in the source program. The name is usually VARCHAR(128); however, if the cursor is defined WITH RETURN, the name is limited to VARCHAR(30).
NO SCROLL or SCROLL
Specifies whether the cursor is scrollable or not scrollable.
NO SCROLL
Specifies that the cursor is not scrollable. This is the default.
SCROLL
Specifies that the cursor is scrollable. For a scrollable cursor, whether the cursor has sensitivity to inserts, updates, or deletes depends on the cursor sensitivity option in effect for the cursor. If a sensitivity option is not specified, ASENSITIVE is the default.
ASENSITIVE
Specifies that the cursor should be as sensitive as possible. This is the default.

A cursor that defined as ASENSITIVE will be either insensitive or sensitive dynamic; it will not be sensitive static. For information about how the effective sensitivity of the cursor is returned to the application with the GET DIAGNOSTICS statement or in the SQLCA, see OPEN.

Start of changeThe sensitivity of a cursor is a factor in the choice of access path. Explicitly specify the sensitivity level that you need, instead of specifying ASENSITIVE.End of change

INSENSITIVE
Specifies that the cursor does not have sensitivity to inserts, updates, or deletes that are made to the rows underlying the result table. As a result, the size of the result table, the order of the rows, and the values for each row do not change after the cursor is opened. In addition, the cursor is read-only. The SELECT statement or attribute-string of the PREPARE statement cannot contain a FOR UPDATE clause, and the cursor cannot be used for positioned updates or deletes.
SENSITIVE
Specifies that the cursor has sensitivity to changes that are made to the database after the result table is materialized. The cursor is always sensitive to updates and deletes that are made using the cursor (that is, positioned updates and deletes using the same cursor). When the current value of a row no longer satisfies the select-statement or statement-name, that row is no longer visible through the cursor. When a row of the result table is deleted from the underlying base table, the row is no longer visible through the cursor.

If DB2® cannot make changes visible to the cursor, then an error is issued at bind time for OPEN CURSOR. DB2 cannot make changes visible to the cursor when the cursor implicitly becomes read-only. For example, when the result table must be materialized, as when the FROM clause of the SELECT statement contains more than one table or view. The current list of conditions that result in an implicit read-only cursor can be found in Read-only cursors.

The default is DYNAMIC.

DYNAMIC
Specifies that the result table of the cursor is dynamic, meaning that the size of the result table might change after the cursor is opened as rows are inserted into or deleted from the underlying table, and the order of the rows might change. Rows that are inserted, deleted, or updated by statements that are executed by the same application process as the cursor are visible to the cursor immediately. Rows that are inserted, deleted, or updated by statements that are executed by other application processes are visible only after the statements are committed. If a column for an ORDER BY clause is updated via a cursor or any means outside the process, the next FETCH statement behaves as if the updated row was deleted and re-inserted into the result table at its correct location. At the time of a positioned update, the cursor is positioned before the next row of the original location and there is no current row, making the row appear to have moved.

If a SENSITIVE DYNAMIC cursor is not possible, an error is returned. For example, if a temporary table is needed an error is returned. The SELECT statement of a cursor that is defined as SENSITIVE DYNAMIC cannot contain an SQL data change statement.

The FETCH FIRST n ROWS ONLY clause must not be specified for the outermost fullselect for a sensitive dynamic cursor.

STATIC
Specifies that the size of the result table and the order of the rows do not change after the cursor is opened. Rows inserted into the underlying table are not added to the result table regardless of how the rows are inserted. Rows in the result table do not move if columns in the ORDER BY clause are updated in rows that have already been materialized. Positioned updates and deletes are allowed if the result table is updatable. The SELECT statement of a cursor that is defined as SENSITIVE STATIC cannot contain an SQL data change statement.

A STATIC cursor has visibility to changes made by this cursor using positioned updates or deletes. Committed changes made outside this cursor are visible with the SENSITIVE option of the FETCH statement. A FETCH SENSITIVE can result in a hole in the result table (that is, a difference between the result table and its underlying base table). If an updated row in the base table of a cursor no longer satisfies the predicate of its SELECT statement, an update hole occurs in the result table. If a row of a cursor was deleted in the base table, a delete hole occurs in the result table. When a FETCH SENSITIVE detects an update hole, no data is returned (a warning is issued), and the cursor is left positioned on the update hole. When a FETCH SENSITIVE detects a delete hole, no data is returned (a warning is issued), and the cursor is left positioned on the delete hole.

Updates through a cursor result in an automatic re-fetch of the row. This re-fetch means that updates can create a hole themselves. The re-fetched row also reflects changes as a result of triggers updating the same row. It is important to reflect these changes to maintain the consistency of data in the row.

Using a function that is not deterministic (built-in or user-defined) in the WHERE clause of the select-statement or statement-name of a SENSITIVE STATIC cursor can cause misleading results. This situation occurs because DB2 constructs a temporary result table and retrieves rows from this table for FETCH INSENSITIVE statements. When DB2 processes a FETCH SENSITIVE statement, rows are fetched from the underlying table and predicates are re-evaluated. Using a function that is not deterministic can yield a different result on each FETCH SENSITIVE of the same row, which could also result in the row no longer being considered a match.

A FETCH INSENSITIVE on a SENSITIVE STATIC SCROLL cursor is not sensitive to changes made outside the cursor, unless a previous FETCH SENSITIVE has already refreshed that row; however, positioned updates and delete changes with the cursor are visible.

STATIC cursors are insensitive to insertions.

WITHOUT HOLD or WITH HOLD
Specifies whether the cursor should be prevented from being closed as a consequence of a commit operation.
WITHOUT HOLD
Does not prevent the cursor from being closed as a consequence of a commit operation. This is the default.
WITH HOLD
Prevents the cursor from being closed as a consequence of a commit operation. A cursor declared with WITH HOLD is closed at commit time if one of the following is true:
  • The connection associated with the cursor is in the release pending status.
  • The bind option DISCONNECT(AUTOMATIC) is in effect.
  • The environment is one in which the option WITH HOLD is ignored.

When WITH HOLD is specified, a commit operation commits all of the changes in the current unit of work. For example, with a non-scrollable cursor, an initial FETCH statement is needed after a COMMIT statement to position the cursor on the row that follows the row that the cursor was positioned on before the commit operation.

WITH HOLD has no effect on an SQL data change statement within a SELECT statement. When a COMMIT is issued, the changes caused by the SQL data change statement are committed, regardless of whether or not the cursor is declared WITH HOLD.

All cursors are implicitly closed by a connect (Type 1) or rollback operation. A cursor is also implicitly closed by a commit operation if WITH HOLD is ignored or not specified.

Cursors that are declared with WITH HOLD in CICS® or in IMS™ non-message-driven programs will not be closed by a rollback operation if the cursor was opened in a previous unit of work and no changes have been made to the database in the current unit of work. The cursor cannot be closed because CICS and IMS do not broadcast the rollback request to DB2 for a null unit of work.

If a cursor is closed before the commit operation, the effect is the same as if the cursor was declared without the option WITH HOLD.

WITH HOLD is ignored in IMS message driven programs (MPP, IFP, and message-driven BMP). WITH HOLD maintains the cursor position in a CICS pseudo-conversational program until the end-of-task (EOT).

For details on restrictions that apply to declaring cursors with WITH HOLD, see DB2 Application Programming and SQL Guide.

WITHOUT RETURN or WITH RETURN
Specifies whether the result table of the cursor is intended to be used as a result set that will be returned from a procedure. If statement-name is specified, the default is the corresponding prepare attribute of the statement. Otherwise, the default is WITHOUT RETURN.
WITHOUT RETURN
Specifies that the result table of the cursor is not intended to be used as a result set that will be returned from a procedure.
Start of changeWITH RETURNEnd of change
Start of changeSpecifies that the result table of the cursor is intended to be used as a result set that will be returned from a procedure. WITH RETURN is relevant only if the DECLARE CURSOR statement is contained within the source code for a procedure. In other cases, the precompiler might accept the clause, but it has not effect.

When a cursor that is declared using the WITH RETURN TO CALLER clause remains open at the end of a program or routine, that cursor defines a result set from the program or routine. Use the CLOSE statement to close a cursor that is not intended to be a result set from the program or routine. Although DB2 will automatically close any cursors that are not declared using with a WITH RETURN clause, the use of the CLOSE statement is recommended to increase the portability of applications.

For non-scrollable cursors, the result set consists of all rows from the current cursor position to the end of the result table. For scrollable cursors, the result set consists of all rows of the result table.

Start of changeTO CALLEREnd of change
Start of changeSpecifies that the cursor can return a result set to the caller of the procedure. The caller is the program or routine that executed the SQL CALL statement that invokes the procedure that contains the DECLARE CURSOR statement. For example, if the caller is a procedure, the result set, is returned to the procedure. If the caller is a client application, the result set is returned to the client application.

If the statement is contained within the source code for a procedure, WITH RETURN TO CALLER specifies that the cursor can be used as a result set cursor. A result set cursor is used when the result table of a cursor is to be returned from a procedure. Specifying TO CALLER is optional.

In other cases, the clause is ignored and the cursor cannot be used as a result set cursor.

End of change
TO CLIENT
Specifies that the cursor can return a result set to the client application. This cursor is invisible to any intermediate nested procedures. If a function or trigger calls the procedure (either directly or indirectly), the result set cannot be returned to the client and the cursor will be closed after the procedure finishes.
End of change
rowset-positioning
Specifies whether multiple rows of data can be accessed as a rowset on a single FETCH statement for the cursor. The default is WITHOUT ROWSET POSITIONING.
WITHOUT ROWSET POSITIONING
Specifies that the cursor can be used only with row-positioned FETCH statements. The cursor is to return a single row for each FETCH statement and the FOR n ROWS clause cannot be specified on a FETCH statement for this cursor. WITHOUT ROWSET POSITIONING or single row access refers to how data is fetched from the database engine. For remote access, data might be blocked and returned to the client in blocks.
WITH ROWSET POSITIONING
Specifies that the cursor can be used with either row-positioned or rowset-positioned FETCH statements. This cursor can be used to return either a single row or multiple rows, as a rowset, with a single FETCH statement. ROWSET POSITIONING refers to how data is fetched from the database engine. For remote access, if any row qualifies, at least 1 row is returned as a rowset. The size of the rowset depends on the number of rows specified on the FETCH statement and on the number of rows that qualify. Data might be blocked and returned to the client in blocks.

Start of changeDB2 REXX applications do not support cursors that are declared WITH ROWSET POSITIONING. To allow a cursor for a SELECT statement in a DB2 REXX application to be used with row-positioned or rowset-positioned FETCH statements, specify WITH ROWSET POSITIONING in the attribute string of the PREPARE statement for the SELECT statement.End of change

select-statement
Specifies the result table of the cursor. See select-statement for an explanation of select-statement.

The select-statement must not include parameter markers (except for REXX), but can include references to host variables. In host languages, other than REXX, the declarations of the host variables must precede the DECLARE CURSOR statement in the source program. In REXX, parameter markers must be used in place of host variables and the statement must be prepared.

The USING clause of the OPEN statement can be used to specify host variables that will override the values of the host variables or parameter markers that are specified as part of the statement in the DECLARE CURSOR statement.

Start of changeThe select-statement must not contain an SQL data change statement if the cursor is defined as SENSITIVE DYNAMIC or SENSITIVE STATIC.End of change

statement-name
Identifies the prepared select-statement that specifies the result table of the cursor whenever the cursor is opened. The statement-name must not be identical to a statement name specified in another DECLARE CURSOR statement of the source program. For an explanation of prepared SELECT statements, see PREPARE.

Start of changeThe prepared select-statement must not contain an SQL data change statement if the cursor is defined as SENSITIVE DYNAMIC or SENSITIVE STATIC.End of change

Notes

A cursor in the open state designates a result table and a position relative to the rows of that table. The table is the result table specified by the SELECT statement of the cursor.

Read-only cursors:
If the result table is read-only, the cursor is read-only. The cursor that references a view with instead of triggers are read-only since positioned UPDATE and positioned DELETE statements are not allowed using those cursors. The result table is read-only if one or more of the following statements is true about the select-statement of the cursor:
  • The first FROM clause identifies or contains any of the following:
    • More than one table or view
    • A catalog table with no updatable columns
    • A read-only view
    • A nested table expression
    • A table function
    • A system-maintained materialized query table
    • Start of changeA single table that is a system-period temporal table and a period specification is usedEnd of change
  • The first SELECT clause specifies the keyword DISTINCT, contains an aggregate function, or uses both
  • It contains an SQL data change statement
  • The outer subselect contains a GROUP BY clause, a HAVING clause, or both clauses
  • It contains a subquery such that the base object of the outer subselect, and of the subquery, is the same table
  • Any of the following operators or clauses are specified:
    • A set operator
    • An ORDER BY clause (except when the cursor is declared as SENSITIVE STATIC scrollable)
    • A FOR READ ONLY clause
  • It is executed with isolation level UR and a FOR UPDATE clause is not specified.
  • Start of changeIt is a VALUES clause.End of change

If the result table is not read-only, the cursor can be used to update or delete the underlying rows of the result table.

Start of changeTables for which row or column access controls are enforced:End of change
Start of changeThe select-statement of the cursor can reference a table for which row or column access controls are enforced. The row or column access controls do not effect the determination of whether the cursor is read-only and do not effect the cursor sensitivity.End of change
Work file database requirement for static scrollable cursors:
To use a static scrollable cursor, you must first create a work file database and at least one table space with a 32KB page size in this database because a static scrollable cursor requires a temporary table for its result table while the cursor is open. DB2 chooses a table space to use for the temporary result table. Dynamic scrollable cursors do not require a declared temporary table.

For static scrollable cursor declarations that contain empty strings, DB2 assigns one byte in the temporary table space for each empty string. The following example shows a scrollable cursor declaration with an empty string:

EXEC SQL DECLARE CSROWSTAT SENSITIVE STATIC SCROLL CURSOR
  WITH ROWSET POSITIONING WITH HOLD FOR
  SELECT ID1,'' 
  FROM TB;  
Cursors in COBOL and Fortran programs:
In COBOL and Fortran source programs, the DECLARE CURSOR statement must precede all statements that explicitly refer to the cursor by name. This rule does not necessarily apply to the other host languages because the precompiler provides a two-pass option for these languages. This rule applies to other host languages if the two-pass option is not used.
Cursors in REXX:
If host variables are used in a DECLARE CURSOR statement within a REXX procedure, the DECLARE CURSOR statement must be the object of a PREPARE and EXECUTE.
Scope of a cursor:
The scope of cursor-name is the source program in which it is defined; that is, the application program submitted to the precompiler. Thus, you can only refer to a cursor by statements that are precompiled with the cursor declaration. For example, a COBOL program called from another program cannot use a cursor that was opened by the calling program. Furthermore, a cursor defined in a Fortran subprogram can only be referred to in that subprogram. Cursors that specify WITH RETURN in a procedure and are left open are returned as result sets.
Although the scope of a cursor is the program in which it is declared, each package (or DBRM of a plan) created from the program includes a separate instance of the cursor, and more than one instance of the cursor can be used in the same execution of the program. For example, assume a program is precompiled with the CONNECT(2) option and its DBRM is used to create a package at location X and a package at location Y. The program contains the following SQL statements:
  DECLARE C CURSOR FOR ...
  CONNECT TO X
  OPEN C
  FETCH C INTO ...
  CONNECT TO Y
  OPEN C
  FETCH C INTO ...

The second OPEN C statement does not cause an error because it refers to a different instance of cursor C. The same notion applies to a single location if the packages are in different collections.

A SELECT statement is evaluated at the time the cursor is opened. If the same cursor is opened, closed, and then opened again, the results can be different. If the SELECT statement of the cursor contains CURRENT DATE, CURRENT TIME or CURRENT TIMESTAMP, all references to these special registers yields the same respective datetime value on each FETCH operation. The value is determined when the cursor is opened. Multiple cursors using the same SELECT statement can be opened concurrently. They are each considered independent activities.

Blocking of data:
To process data more efficiently, DB2 might block data for read-only cursors. If a cursor is not going to be used in a positioned UPDATE or positioned DELETE statement, define the cursor as FOR READ ONLY.
Positioned deletes and isolation level UR:
Specify FOR UPDATE if you want to use the cursor for a positioned DELETE and the isolation level is UR because of a BIND option. In this case, the isolation level is CS.
Returning a result set from a stored procedure:
A cursor that is declared in a stored procedure returns a result set when all of the following conditions are true:
  • The cursor is declared with the WITH RETURN option. In a distributed environment, blocks of each result set of the cursor's data are returned with the CALL statement reply.
  • The cursor is left open after exiting from the stored procedure. A cursor declared with the SCROLL option must be left positioned before the first row before exiting from the stored procedure.
  • The cursor is declared with the WITH HOLD option if the stored procedure is defined to commit on return.

The result set is the set of all rows after the current position of the cursor after exiting the stored procedure. The result set is assumed to be read-only. If that same procedure is invoked again, open result set cursors for a stored procedure at a given site are automatically closed by the database management system.

Scrollable cursors specified with user-defined functions:
A row can be fetched more than once with a scrollable cursor. Therefore, if a scrollable cursor is defined with a function that is not deterministic in the select list of the cursor, a row can be fetched multiple times with different results for each fetch. (However, the value of a function that is not deterministic in the WHERE clause of a scrollable cursor is captured when the cursor is opened and remains unchanged until the cursor is closed.) Similarly, if a scrollable cursor is defined with a user-defined function with external action, the action is executed with every fetch.

Start of changeMultiple instances of a cursor that is defined with RETURN TO CLIENT: If the cursor is declared in a native SQL procedure, a cursor that is declared as WITH RETURN TO CLIENT can be opened even when a cursor with the same name is already in the open state. In this case, the already open cursor becomes a result set cursor and is no longer accessible by using its cursor name. A new cursor is opened and becomes accessible by using the cursor name. When a CLOSE statement is issued, the last instance of the cursor will be closed. Closing the new cursor does not make the cursor that was previously accessible by that name accessible by the cursor name again. Cursors that become result set cursors in this way cannot be accessed at the server and can be processed only at the client.End of change

Examples

The statements in the following examples are assumed to be in PL/I programs.

Example 1: Declare C1 as the cursor of a query to retrieve data from the table DSN8A10.DEPT. The query itself appears in the DECLARE CURSOR statement.
   EXEC SQL DECLARE C1 CURSOR FOR
      SELECT DEPTNO, DEPTNAME, MGRNO
      FROM DSN8A10.DEPT
      WHERE ADMRDEPT = 'A00';
Example 2: Declare C1 as the cursor of a query to retrieve data from the table DSN8810.DEPT. Assume that the data will be updated later with a searched update and should be locked when the query executes. The query itself appears in the DECLARE CURSOR statement.
   EXEC SQL DECLARE C1 CURSOR FOR
      SELECT DEPTNO, DEPTNAME, MGRNO
      FROM DSN8A10.DEPT
      WHERE ADMRDEPT = 'A00'
      FOR READ ONLY WITH RS USE AND KEEP EXCLUSIVE LOCKS;
Example 3: Declare C2 as the cursor for a statement named STMT2.
   EXEC SQL DECLARE C2 CURSOR FOR STMT2;
Example 4: Declare C3® as the cursor for a query to be used in positioned updates of the table DSN8A10.EMP. Allow the completed updates to be committed from time to time without closing the cursor.
   EXEC SQL DECLARE C3 CURSOR WITH HOLD FOR
     SELECT * FROM DSN8A10.EMP
       FOR UPDATE OF WORKDEPT, PHONENO, JOB, EDLEVEL, SALARY;
Instead of specifying which columns should be updated, you could use a FOR UPDATE clause without the names of the columns to indicate that all updatable columns are updated.
Example 5: In stored procedure SP1, declare C4 as the cursor for a query of the table DSN8A10.PROJ. Enable the cursor to return a result set to the caller of SP1, which performs a commit on return.
   EXEC SQL DECLARE C4 CURSOR WITH HOLD WITH RETURN FOR
      SELECT PROJNO, PROJNAME
      FROM DSN8A10.PROJ
      WHERE DEPTNO = 'A01';
Example 6: In the following example, the DECLARE CURSOR statement associates the cursor name C5 with the results of the SELECT and specifies that the cursor is scrollable. C5 allows positioned updates and deletes because the result table can be updated.
   EXEC SQL DECLARE C5 SENSITIVE STATIC SCROLL CURSOR FOR
      SELECT DEPTNO, DEPTNAME, MGRNO
      FROM DSN8A10.DEPT
      WHERE ADMRDEPT = 'A00';
Example 7: In the following example, the DECLARE CURSOR statement associates the cursor name C6 with the results of the SELECT and specifies that the cursor is scrollable.
   EXEC SQL DECLARE C6 INSENSITIVE SCROLL CURSOR FOR
      SELECT DEPTNO, DEPTNAME, MGRNO
      FROM DSN8A10.DEPT
      WHERE DEPTNO;
Example 8: The following example illustrates how an application program might use dynamic scrollable cursors. First create and populate a table.
   CREATE TABLE ORDER
         (ORDERNUM  INTEGER,
          CUSTNUM   INTEGER, 
          CUSTNAME  VARCHAR(20), 
          ORDERDATE CHAR(8), 
          ORDERAMT  DECIMAL(8,3),
          COMMENTS  VARCHAR(20));
Populate the table by inserting or loading about 500 rows.
   EXEC SQL DECLARE CURSOR ORDERSCROLL
      SENSITIVE DYNAMIC SCROLL FOR
      SELECT ORDERNUM, CUSTNAME, ORDERAMT, ORDERDATE FROM ORDER 
      WHERE ORDERAMT > 1000
      FOR UPDATE OF COMMENTS;
Open the scrollable cursor.
   OPEN CURSOR ORDERSCROLL;
Fetch forward from the scrollable cursor.
   -- Loop-to-fill-screen
         -- do 10 times 
          FETCH FROM ORDERSCROLL INTO :HV1, :HV2, :HV3, :HV4;
         -- end 
Fetch RELATIVE from the scrollable cursor.
   -- Skip-forward-100-rows
         FETCH RELATIVE +100 
          FROM ORDERSCROLL INTO :HV1, :HV2, :HV3, :HV4;
        
   -- Skip-backward-50-rows
         FETCH RELATIVE -50 
          FROM ORDERSCROLL INTO :HV1, :HV2, :HV3, :HV4;
        
Fetch ABSOLUTE from the scrollable cursor.
   -- Re-read-the-third-row
         FETCH ABSOLUTE +3 
          FROM ORDERSCROLL INTO :HV1, :HV2, :HV3, :HV4;
        
Fetch RELATIVE from scrollable cursor.
   -- Read-the-third-row-from current position
         FETCH SENSITIVE RELATIVE +3 
          FROM ORDERSCROLL INTO :HV1, :HV2, :HV3, :HV4;
        
Do a positioned update through the scrollable cursor.
   -- Update-the-current-row
         UPDATE ORDER SET COMMENTS = "Expedite" 
          WHERE CURRENT OF ORDERSCROLL;
        
Close the scrollable cursor.
   CLOSE CURSOR ORDERSCROLL;
Example 9: Declare C1 as the cursor of a query to retrieve a rowset from the table DEPT. The prepared statement is MYCURSOR.
   EXEC SQL DECLARE C1 CURSOR 
      WITH ROWSET POSITIONING FOR MYCURSOR;