FETCH

The FETCH statement positions a cursor on a row of its result table. It can return zero, one, or multiple rows and assigns the values of the rows to variables if there is a target specification.

Invocation

This statement can only be embedded in an application program. It is an executable statement that cannot be dynamically prepared. Multiple row fetch is not supported in REXX, Fortran, or SQL Procedure applications1. Start of changeThe FETCH statement with the WITH CONTINUE clause is not supported in REXX.End of change

Authorization

See DECLARE CURSOR for an explanation of the authorization required to use a cursor.

Syntax

Read syntax diagram
>>-FETCH--+---------------+--+-------------------+-------------->
          +-INSENSITIVE---+  |               (2) |   
          |           (1) |  '-WITH CONTINUE-----'   
          '-SENSITIVE-----'                          

                          .-FROM-.                
>--| fetch-orientation |--+------+--cursor-name----------------->

>--+----------------------------+------------------------------><
   +-| single-row-fetch |-------+   
   |                        (3) |   
   '-| multiple-row-fetch |-----'   

Notes:
  1. If INSENSITIVE or SENSITIVE is specified, single-row-fetch or multiple-row-fetch must be specified.
  2. If WITH CONTINUE is specified, single-row-fetch must be specified.
  3. If multiple-row-fetch is specified, a rowset-positioned fetch orientation must also be specified.

fetch-orientation

Read syntax diagram
fetch-orientation

            (1)                    
|--+-BEFORE--------------------+--------------------------------|
   |       (1)                 |   
   +-AFTER---------------------+   
   |                    (2)    |   
   +-| row-positioned |--------+   
   |                       (3) |   
   '-| rowset-positioned |-----'   

row-positioned

   .-NEXT--------------------------.   
|--+-------------------------------+----------------------------|
   +-PRIOR-------------------------+   
   +-FIRST-------------------------+   
   +-LAST--------------------------+   
   +-CURRENT--+----------+---------+   
   |          '-CONTINUE-'         |   
   +-ABSOLUTE-+-host-variable----+-+   
   |          '-integer-constant-' |   
   '-RELATIVE-+-host-variable----+-'   
              '-integer-constant-'     

rowset-positioned

|--+-NEXT ROWSET------------------------------------------+-----|
   +-PRIOR ROWSET-----------------------------------------+   
   +-FIRST ROWSET-----------------------------------------+   
   +-LAST ROWSET------------------------------------------+   
   +-CURRENT ROWSET---------------------------------------+   
   '-ROWSET STARTING AT-+-ABSOLUTE-+-+-host-variable----+-'   
                        '-RELATIVE-' '-integer-constant-'     

Notes:
  1. If BEFORE or AFTER is specified, SENSITIVE, INSENSITIVE, single-row-fetch, or multiple-row-fetch must not be specified.
  2. A row-positioned fetch orientation can be specified only if multiple-row-fetch is not specified.
  3. If multiple-row-fetch is specified, a rowset-positioned fetch orientation must also be specified.

fetch-type

Read syntax diagram
single-row-fetch

|--+---------------------------------+--------------------------|
   |      .-,-------------.          |   
   |      V               | (1)      |   
   +-INTO---host-variable-+----------+   
   '-INTO DESCRIPTOR descriptor-name-'   

multiple-row-fetch

    (2)                                      (3)   
|--------+---------------------------------+-------------------->
         '-FOR--+-host-variable----+--ROWS-'       
                '-integer-constant-'               

>--+---------------------------------+--------------------------|
   |       .-,-------------------.   |   
   |       V                     |   |   
   +-INTO----host-variable-array-+---+   
   '-INTO DESCRIPTOR descriptor-name-'   

Notes:
  1. For single-row-fetch, a host-variable-array can be specified instead of a host variable and the descriptor can describe host-variable-arrays. In either case, data is returned only for the first entry of the host-variable-array.
  2. This clause must not be specified if a row-positioned fetch orientation or if no fetch orientation was specified.
  3. This clause is optional. If this clause is not specified and either a rowset size has not been established yet or a row positioned FETCH statement was the last type of FETCH statement issued for this cursor, the rowset size is implicitly one. If the last FETCH statement issued for this cursor was a rowset positioned FETCH statement and this clause is not specified, the rowset size is the same size as the previous rowset positioned FETCH.

Description

INSENSITIVE
Returns the row from the result table as it is. If the row has been previously fetched with a FETCH SENSITIVE, it reflects changes made outside this cursor before the FETCH SENSITIVE statement was issued. Positioned updates and deletes are reflected with FETCH INSENSITIVE if the same cursor was used for the positioned update or delete.

INSENSITIVE can only be specified for cursors declared as INSENSITIVE or SENSITIVE STATIC (or if the cursor is declared as ASENSITIVE and DB2® defaults to INSENSITIVE). Otherwise, if the cursor is declared as SENSITIVE DYNAMIC (or if the cursor is declared as ASENSITIVE and DB2 defaults to SENSITIVE DYNAMIC), an error occurs and the FETCH statement has no effect. For an INSENSITIVE cursor, specifying INSENSITIVE is optional because it is the default.

SENSITIVE
Updates the fetched row in the result table from the corresponding row in the base table of the cursor's SELECT statement and returns the current values. Thus, it reflects changes made outside this cursor. SENSITIVE can only be specified for a sensitive cursor. Otherwise, if the cursor is insensitive, an error occurs and the FETCH statement has no effect. For a SENSITIVE cursor, specifying SENSITIVE is optional because it is the default.

When the cursor is declared as SENSITIVE STATIC and a FETCH SENSITIVE is requested, the following steps are taken:

  1. DB2 retrieves the row of the database that corresponds to the row of the result table that is about to be fetched.
  2. If the corresponding row has been deleted, a "delete hole" occurs in the result table, a warning is issued, the cursor is repositioned on the "hole", and no data is fetched. (DB2 marks a row in the result table as a "delete hole" when the corresponding row in the database is deleted.)
  3. If the corresponding row has not been deleted, the predicate of the underlying SELECT statement is re-evaluated. If the row no longer satisfies the predicate, an "update hole" occurs in the result table, a warning is issued, the cursor is repositioned on the "hole," and no data is fetched. (DB2 marks a row in the result table as an "update hole" when an update to the corresponding row in the database causes the row to no longer qualify for the result table.)
  4. If the corresponding row does not result in a delete or an update hole in the result table, the cursor is repositioned on the row of the result table and the data is fetched.
WITH CONTINUE
Specifies that the DB2 subsystem should prepare to allow subsequent FETCH CURRENT CONTINUE operations to access any truncated LOB or XML result column following an initial FETCH operation that provides output variables that are not large enough to hold the entire LOB or XML columns. When the WITH CONTINUE clause is specified, the DB2 subsystem takes the following actions that can differ from the case where the FETCH statement does not include the WITH CONTINUE clause:
  • If truncation occurs when returning an XML or LOB column, the DB2 subsystem will remember the truncation position and will not discard the remaining data.
  • If truncation occurs when returning an XML or LOB column, the DB2 subsystem returns the total length that would have been required to hold all of the data of the LOB or XML column. This will either be in the first four bytes of the LOB host variable structure or in the 4 byte area that is pointed to by the SQLDATALEN pointer in the SQLVAR entry of the SQLDA for that host variable. What is returned depends on the programming method that is used. See SQL descriptor area (SQLDA) for details about the SQLDA contents.
  • If returning XML data, the result column will be fully materialized in the database before the data is returned.

If the CURRENT CONTINUE clause is specified, the WITH CONTINUE behavior is assumed.

AFTER
Positions the cursor after the last row of the result table. Values are not assigned to host variables. The number of rows of the result table are returned in the SQLERRD1 and SQLERRD2 fields of the SQLCA for cursors with an effective sensitivity of INSENSITIVE or SENSITIVE STATIC.
BEFORE
Positions the cursor before the first row of the result table. Values are not assigned to host variables.
row-positioned
Positioning of the cursor with row-positioned fetch orientations NEXT, PRIOR, CURRENT and RELATIVE is done in relation to the current cursor position. Following a successful row-positioned FETCH statement, the cursor is positioned on a single row of data. If the cursor is enabled for rowsets, positioning is performed relative to the current row or the first row of the current rowset, and the cursor is positioned on a rowset consisting of a single row.
NEXT
Positions the cursor on the next row or rows of the result table relative to the current cursor position, and returns data if a target is specified. NEXT is the only row-positioned fetch operation that can be explicitly specified for cursors that are defined as NO SCROLL. NEXT is the default if no other cursor positioning is specified. If a specified row reflects a hole, a warning is issued and data values are not assigned to host variables for that row.

Table 1 lists situations for different cursor positions and the results when NEXT is used.

Table 1. Results when NEXT is used with different cursor positions
Current state of the cursor Result of FETCH NEXT
Before the first row Cursor is positioned on the first row1 and data is returned if requested.
On the last row or after the last row A warning occurs, values are not assigned to host variables, and the cursor position is unchanged.
Before a hole For a SENSITIVE STATIC cursor, a warning occurs for a delete hole or an update hole, values are not assigned to host variables, and the cursor is positioned on the hole.
Unknown An error occurs, values are not assigned to host variables, and the cursor position remains unknown.
Note:
  1. This row is not applicable in the case of a forward-only cursor (that is when NO SCROLL was specified implicitly or explicitly).
PRIOR
Positions the cursor on the previous row or rows of the result table relative to the current cursor position, and returns data if a target is specified. If a specified row reflects a hole, a warning is issued, and data values are not assigned to host variables for that row.

Table 2 lists situations for different cursor positions and the results when PRIOR is used.

Table 2. Results when PRIOR is used with different cursor positions
Current state of the cursor Result of FETCH PRIOR
Before the first row or on the first row A warning occurs, values are not assigned to host variables, and the cursor position is unchanged.
After a hole For a SENSITIVE STATIC cursor, a warning occurs for a delete hole or an update hole, values are not assigned to host variables, and the cursor is positioned on the hole.
After the last row Cursor is positioned on the last row.
Unknown An error occurs, values are not assigned to host variables, and the cursor position remains unknown.
FIRST
Positions the cursor on the first row of the result table, and returns data if a target is specified. For a SENSITIVE STATIC cursor, if the first row of the result table is a hole, a warning occurs for a delete hole or an update hole and values are not assigned to host variables.
LAST
Positions the cursor on the last row of the result table, and returns data if a target is specified. The number of rows of the result table is returned in the SQLERRD1 and SQLERRD2 fields of the SQLCA for an insensitive or sensitive static cursor. For a SENSITIVE STATIC cursor, if the last row of the result table is a hole, a warning occurs for a delete hole or an update hole and values are not assigned to host variables.
CURRENT
The cursor position is not changed, data is returned if a target is specified. If the cursor was positioned on a rowset of more than one row, the cursor position is on the first row of the rowset.

Table 3 lists situations in which errors occur with the CURRENT clause.

Table 3. Situations in which errors occur with CURRENT
Current state of the cursor Result of FETCH CURRENT
Before the first row or after the last row A warning occurs, values are not assigned to host variables, and the cursor position is unchanged.
On a hole For a SENSITIVE STATIC, a warning occurs for a delete hole or an update hole, values are not assigned to host variables, and the cursor is positioned on the hole.

If the cursor is defined as a rowset cursor, with isolation level UR or a sensitive dynamic scrollable cursor, it is possible that a different row will be returned than the FETCH that established the most recent cursor position. This can occur while fetching a row again when it is determined to not be there anymore. In this case, fetching continues moving forward to get the row of data.

Unknown An error occurs, values are not assigned to host variables, and the cursor position remains unknown.
CONTINUE
The cursor positioning is not changed, and data is returned if a target is specified. The FETCH CURRENT CONTINUE statement retrieves remaining data for any LOB or XML column result values that were truncated on a previous FETCH or FETCH CURRENT CONTINUE statement. It assigns the remaining data for those truncated columns to the host variables that are referenced in the statement or pointed to by the descriptor. The data that is returned for previously-truncated result values begins at the point of truncation. This form of the CURRENT clause must only be used after a single-row FETCH WITH CONTINUE or FETCH CURRENT CONTINUE statement that has returned partial data for one or more LOB or XML columns. The cursor must be open and positioned on a row.

FETCH CURRENT CONTINUE must pass host variables entries for all columns in the SELECT list, even though the non-LOB columns or non-XML columns will not return any data.

ABSOLUTE
host-variable or integer-constant is assigned to an integral value k. If a host-variable is specified, it must be an exact numeric type with zero scale and must not include an indicator variable. The possible data types for the host variable are DECIMAL(n,0) or integer. The DECIMAL data type is limited to DECIMAL(18,0). An integer-constant can be up to 31 digits, depending on the application language.

If k=0, the cursor is positioned before the first row of the result table. Otherwise, ABSOLUTE positions the cursor to row k of the result table if k>0, or to k rows from the bottom of the table if k<0. For example, "ABSOLUTE -1" is the same as "LAST".

Data is returned if the specified position is within the rows of the result table, and a target is specified.

If an absolute position is specified that is before the first row or after the last row of the result table, a warning occurs, values are not assigned to host variables, and the cursor is positioned either before the first row or after the last row. If the resulting cursor position is after the last row for INSENSITIVE and SENSITIVE STATIC scrollable cursors, the number of rows of the result table are returned in the SQLERRD1 and SQLERRD2 fields of the SQLCA. If row k of the result table is a hole, a warning occurs and values are not assigned to host variables.

FETCH ABSOLUTE 0 results in positioning before the first row and a warning is issued. FETCH BEFORE results in positioning before the first row and no warning is issued.

Table 4 lists some synonymous specifications.

Table 4. Synonymous scroll specifications for ABSOLUTE
Specification Alternative
ABSOLUTE 0 (but with a warning) BEFORE (without a warning)
ABSOLUTE +1 FIRST
ABSOLUTE -1 LAST
ABSOLUTE -m, 0<m≤n ABSOLUTE n+1-m
ABSOLUTE n LAST
ABSOLUTE -n FIRST
ABSOLUTE x (with a warning) AFTER (without a warning)
ABSOLUTE -x (with a warning) BEFORE (without a warning)
Note: Assume: 0<=m<=n<x Where, n is the number of rows in the result table.
RELATIVE
host-variable or integer-constant is assigned to an integral value k. If a host-variable is specified, it must be an exact numeric type with zero scale and must not include an indicator variable. The possible data types for the host variable are DECIMAL(n,0) or integer. The DECIMAL data type is limited to DECIMAL(18,0).

If the cursor is positioned before the first row, or after the last row of the result table, the cursor position is determined as follows:

  • If n is 0, the cursor position is unchanged, values are not assigned to host variables, and a warning occurs
  • If n is positive, and the cursor is positioned before the first row, the cursor is positioned on a rowset starting at row n
  • If n is positive, and the cursor is positioned after the last row, a warning occurs
  • If n is negative, and the cursor is positioned before the first row, a warning occurs
  • If n is negative, and the cursor is positioned after the last row, the cursor is positioned on a rowset starting as row n from the end of the result table

An integer-constant can be up to 31 digits, depending on the application language.

Data is returned if the specified position is within the rows of the result table, and a target is specified.

RELATIVE positions the cursor to the row in the result table that is either k rows after the current row if k>0, or ABS(k) rows before the current row if k<0. For example, "RELATIVE -1" is the same as "PRIOR". If k=0, the position of the cursor does not change (that is, "RELATIVE 0" is the same as "CURRENT").

If a relative position is specified that results in positioning before the first row or after the last row, a warning is issued, values are not assigned to host variables, and the cursor is positioned either before the first row or after the last row. If the resulting cursor position is after the last row for INSENSITIVE and SENSITIVE STATIC scrollable cursors, the number of rows of the result table is returned in the SQLERRD1 and SQLERRD2 fields of the SQLCA. If the cursor is positioned on a hole and RELATIVE 0 is specified or if the target row is a hole, a warning occurs and values are not assigned to host variables.

If the cursor is defined as a rowset cursor, with isolation level UR or a sensitive dynamic scrollable cursor, it is possible that a different row will be returned than the FETCH that established the most recent cursor position. This can occur while fetching a row again when it is determined to not be there anymore. In this case, fetching continues moving forward to get the row data.

If the cursor position is unknown and RELATIVE 0 is specified, an error occurs.

Table 5 lists some synonymous specifications.

Table 5. Synonymous Scroll Specifications for RELATIVE
Specification Alternative
RELATIVE +1 NEXT
RELATIVE -1 PRIOR
RELATIVE 0 CURRENT
RELATIVE +r (with a warning) AFTER (without a warning)
RELATIVE -r (with a warning) BEFORE (without a warning)
Note: r has to be large enough to position the cursor beyond either end of the result table.
rowset-positioned

Positioning of the cursor with rowset-positioned fetch orientations NEXT ROWSET, PRIOR ROWSET, CURRENT ROWSET, and ROWSET STARTING AT RELATIVE is done in relation to the current cursor position. Following a successful rowset-positioned FETCH statement, the cursor is positioned on a rowset of data. The number of rows in the rowset is determined either explicitly or implicitly. The FOR n ROWS clause in the multiple-row-fetch clause is used to explicitly specify the size of the rowset. Positioning is performed relative to the current row or first row of the current rowset, and the cursor is positioned on all rows of the rowset.

A rowset-positioned fetch orientation must not be specified if the current cursor position is not defined to access rowsets. NEXT ROWSET is the only rowset-positioned fetch orientation that can be specified for cursors that are defined as NO SCROLL.

If a row of the rowset reflects a hole, a warning is returned, data values are not assigned to host variable arrays for that row (that is, the corresponding positions in the target host variable arrays are untouched), and -3 is returned in all provided indicator variables for that row. If a hole is detected, and at least one indicator variable is not provided, an error occurs.

NEXT ROWSET
Positions the cursor on the next rowset of the result table relative to the current cursor position, and returns data if a target is specified. The next rowset is logically obtained by fetching the row that follows the current rowset and fetching additional rows until the number of rows that is specified implicitly or explicitly in the FOR n ROWS clause is obtained or the last row of the result table is reached.

If the cursor is positioned before the first row of the result table, the cursor is positioned on the first rowset.

If the cursor is positioned on the last row or after the last row of the result table, the cursor position is unchanged, values are not assigned to host variable arrays, and a warning occurs.

If a row of the rowset reflects a hole, the following actions occur:

  • A warning is returned.
  • Data values are not assigned to the host-variable-arrays for that row (that is, the corresponding positions in the target host-variable-arrays are untouched).
  • A value of -3 is returned in all of the indicator variables that are provided for the row.

If a hole is detected and at least one indicator variable is not provided, an error is returned.

If the cursor is not positioned because of a prior error, values are not assigned to the host-variable-array, and an error is returned. If a row of the rowset would be after the last row of the result table, values are not assigned to host-variable-arrays for that row and any subsequent requested rows of the rowset, and a warning is returned.

NEXT ROWSET is the only rowset positioned fetch orientation that can be explicitly be specified for cursors that are defined as NO SCROLL.

PRIOR ROWSET
Positions the cursor on the previous rowset of the result table relative to the current position, and returns data if a target is specified.

The prior rowset is logically obtained by fetching the row that precedes the current rowset and fetching additional rows until the number of rows that is specified implicitly or explicitly in the FOR n ROWS clause is obtained or the last row of the result table is reached.

If the cursor is positioned after the last row of the result table, the cursor is positioned on the last rowset.

If the cursor is positioned before the first row or on the first row of the result table, the cursor position is unchanged, values are not assigned to host variable arrays, and a warning occurs.

If a row would be before the first row of the result table, the cursor is positioned on a partial rowset that consists of only those rows that are prior to the current position of the cursor starting with the first row of the result table, and a warning is returned. Values are not assigned to the host-variable-arrays for the rows in the rowset for which the warning is returned.

Although the rowset is logically obtained by fetching backwards from before the current rowset, the data is returned to the application starting with the first row of the rowset, to the end of the rowset.

If a row of the rowset reflects a hole, the following actions occur:

  • A warning is returned.
  • Data values are not assigned to the host-variable-arrays for that row (that is, the corresponding positions in the target host-variable-arrays are untouched).
  • A value of -3 is returned in all of the indicator variables that are provided for the row.

If a hole is detected and at least one indicator variable is not provided, an error is returned.

If the cursor is not positioned because of a prior error, values are not assigned to the host-variable-array, and an error is returned.

FIRST ROWSET
Positions the cursor on the first rowset of the result table, and returns data if a target is specified.

If a row of the rowset reflects a hole, the following actions occur:

  • A warning is returned.
  • Data values are not assigned to the host-variable-arrays for that row (that is, the corresponding positions in the target host-variable-arrays are untouched).
  • A value of -3 is returned in all of the indicator variables that are provided for the row.

If a hole is detected and at least one indicator variable is not provided, an error is returned.

If the result table contains fewer rows than specified implicitly or explicitly in the FOR n ROWS clause, values are not assigned to host-variable-arrays after the last row of the result table, and a warning is returned.

LAST ROWSET
Positions the cursor on the last rowset of the result table and returns data if a target is specified. The last rowset is logically obtained by fetching the last row of the result table and fetching prior rows until the number of rows in the rowset is obtained or the first row of the result table is reached. Although the rowset is logically obtained by fetching backwards from the bottom of the result table, the data is returned to the application starting with the first row of the rowset, to the end of the rowset, which is also the end of the result table.

If a row of the rowset reflects a hole, the following actions occur:

  • A warning is returned.
  • Data values are not assigned to the host-variable-arrays for that row (that is, the corresponding positions in the target host-variable-arrays are untouched).
  • A value of -3 is returned in all of the indicator variables that are provided for the row.

If a hole is detected and at least one indicator variable is not provided, an error is returned.

If the result table contains fewer rows than specified implicitly or explicitly in the FOR n ROWS clause, the last rowset is the same as the first rowset, values are not assigned to host-variable-arrays after the last row of the result table, and a warning is returned.

CURRENT ROWSET
If the FOR n ROWS clause specifies a number different from the number of rows specified implicitly or explicitly in the FOR n ROWS clause on the most recent FETCH statement for this cursor, the cursor is repositioned on the specified number of rows, starting with the first row of the current rowset. If the cursor is positioned before the first row, or after the last row of the result table, the cursor position is unchanged, values are not assigned to host variable arrays, and a warning occurs. If the FOR n ROWS clause is not specified, it is possible that the FETCH statement will position the cursor on a partial rowset when the FETCH CURRENT ROWSET statement is processed. In this case, DB2 attempts to position the cursor on a full rowset starting with the first row of the current rowset. Otherwise, the position of the cursor on the current rowset is unchanged. Data is returned if a target is specified.

With isolation level UR or a sensitive dynamic scrollable cursor, it is possible that different rows will be returned than the FETCH that established the most recent rowset cursor position. This can occur while refetching the first row of the rowset when it is determined to not be there anymore. In this case, fetching continues moving forward to get the first row of data for the rowset. This can also occur when changes have been made to other rows in the current rowset such that they no longer exist or have been logically moved within (or out of) the result table of the cursor.

If the cursor is not positioned because of a prior error, values are not assigned to the host-variable-array, and an error occurs.

If the current rowset contains fewer rows than specified implicitly or explicitly in the FOR n ROWS clause, values are not assigned to host-variable-arrays after the last row, and a warning is returned.

ROWSET STARTING AT ABSOLUTE or RELATIVE host-variable or integer-constant
Positions the cursor on the rowset beginning at the row of the result table that is indicated by the ABSOLUTE or RELATIVE specification, and returns data if a target is specified.

host-variable or integer-constant is assigned to an integral value k. If host-variable is specified, it must be an exact numeric type with scale zero, and must not include an indicator variable. The possible data types for the host variable are DECIMAL(n,0) or integer, where the DECIMAL data type is limited to DECIMAL(18,0). If a constant is specified, the value must be an integer.

If a row of the result table would be after the last row or before the first row of the result table, values are not assigned to host-variable-arrays for that row and a warning is returned.

ABSOLUTE
If k=0, an error occurs. If k>0, the first row of the rowset is row k. If k<0, the rowset is positioned on the ABS(k) rows from the bottom of the result table. Assume that ABS(k) is equal to the number of rows for the rowset and that there are enough row to return a complete rowset:
  • FETCH ROWSET STARTING AT ABSOLUTE -k is the same as FETCH LAST ROWSET.
  • FETCH ROWSET STARTING AT ABSOLUTE 1 is the same as FETCH FIRST ROWSET.
RELATIVE
If k=0 and the FOR n ROWS clause does not specify a number different from the number most recently specified implicitly or explicitly for this cursor, then the position of the cursor does not change (that is, "RELATIVE ROWSET 0" is the same as "CURRENT ROWSET"). If k=0 and the FOR n ROWS clause specifies a number different from the number most recently specified implicitly or explicitly for this cursor, then the cursor is repositioned on the specified number of rows, starting with the first row of the current rowset.

If the cursor is positioned before the first row, or after the last row of the result table, the cursor position is determined as follows:

  • If n is 0, the cursor position is unchanged, values are not assigned to host variables, and a warning occurs. This is the same as FETCH CURRENT ROWSET.
  • If n is positive, and the cursor is positioned before the first row, the cursor is positioned on a rowset starting a row n.
  • If n is positive, and the cursor is positioned after the last row, a warning occurs.
  • If n is negative, and the cursor is positioned before the first row, a warning occurs.
  • If n is negative, and the cursor is positioned after the last row, the cursor is positioned on a rowset starting at row n from the bottom of the result table.
Otherwise, RELATIVE repositions the cursor so that the first row of the new rowset cursor position is on the row in the result table that is either k rows after the first row of the current rowset cursor position if k>0, or ABS(k) rows before the first row of the current rowset cursor position if k<0. Assume that ABS(k) is equal to the number of rows for the resulting rowset
  • FETCH ROWSET STARTING AT RELATIVE -k is the same as FETCH PRIOR ROWSET.
  • FETCH ROWSET STARTING AT RELATIVE k is the same as FETCH NEXT ROWSET.
  • FETCH ROWSET STARTING AT RELATIVE 0 is the same as FETCH CURRENT ROWSET.

When ROWSET STARTING AT RELATIVE -n is specified and there are not enough rows between the current position of the cursor and the beginning of the result table to return a complete rowset:

  • A warning is returned.
  • Values are not assigned to the host-variable-arrays.
  • The cursor is positioned before the first row.

If a row of the rowset reflects a hole, If a row of the rowset reflects a hole, the following actions occur:

  • A warning is returned.
  • Data values are not assigned to the host-variable-arrays for that row (that is, the corresponding positions in the target host-variable-arrays are untouched).
  • A value of -3 is returned in all of the indicator variables that are provided for the row.

If a hole is detected and at least one indicator variable is not provided, an error is returned. If a row of the rowset is unknown, values are not assigned to host variable arrays for that row, and an error is returned. If a row of the rowset would be after the last row or before the first row of the result table, values are not assigned to host-variable-arrays for that row, and a warning is returned.

cursor-name
Identifies the cursor to be used in the fetch operation. The cursor name must identify a declared cursor, as explained in the description of the DECLARE CURSOR statement in DECLARE CURSOR, or an allocated cursor, as explained in ALLOCATE CURSOR. When the FETCH statement is executed, the cursor must be in the open state.

If a single-row-fetch or multiple-row-fetch clause is not specified, the cursor position is adjusted as specified, but no data is returned to the user.

single-row-fetch
When single-row-fetch is specified, SENSITIVE or INSENSITIVE can be specified though there is a default. The default depends on the sensitivity of the cursor. If the sensitivity of the cursor is INSENSITIVE, then the default is INSENSITIVE. If the effective sensitivity of the cursor is SENSITIVE DYNAMIC or SENSITIVE STATIC, then the default is SENSITIVE. The single-row-fetch or multiple-row-fetch clause must not be specified when the FETCH BEFORE or FETCH AFTER option is specified. They are required when FETCH BEFORE or FETCH AFTER is not specified. If an individual fetch operation causes the cursor to be positioned or to remain positioned on a row if there is a target specification, the values of the result table are assigned to host variables as specified by the single-fetch-clause.
INTO host-variable,...
Specifies a list of host variables. Each host-variable must identify a structure or variable that is described in the application program in accordance with the rules for declaring host structures and variables. A reference to a structure is replaced by a reference to each of its variables. The first value in the result row is assigned to the first host variable, the second value to the second host variable, and so on.
INTO DESCRIPTOR descriptor-name
Identifies an SQLDA that contains a valid description of the host output variables. Result values from the associated SELECT statement are returned to the application program in the output host variables.

Before the FETCH statement is processed, you must set the following fields in the SQLDA:

  • SQLN to indicate the number of SQLVAR occurrences provided in the SQLDA

    A REXX SQLDA does not contain this field.

  • SQLABC to indicate the number of bytes of storage allocated in the SQLDA
  • SQLD to indicate the number of variables used in the SQLDA when processing the statement
  • SQLVAR occurrences to indicate the attributes of the variables

The SQLDA must have enough storage to contain all SQLVAR occurrences. Each SQLVAR occurrence describes a host variable or buffer into which a value in the result table is to be assigned. If LOBs are present in the results, there must be additional SQLVAR entries for each column of the result table. If the result table contains only base types and distinct types, multiple SQLVAR entries are not needed for each column. However, extra SQLVAR entries are needed for distinct types as well as for LOBs in DESCRIBE and PREPARE INTO statements. For more information on the SQLDA, which includes a description of the SQLVAR and an explanation on how to determine the number of SQLVAR occurrences, see SQL descriptor area (SQLDA).

SQLD must be set to a value greater than or equal to zero and less than or equal to SQLN.

See Identifying an SQLDA in C or C++ for how to represent descriptor-name in C.

multiple-row-fetch
Retrieves multiple rows of data from the result table of a query. The FOR n ROWS clause of the FETCH statement controls how many rows are returned on a single FETCH statement. The fetch orientation determines whether the resulting cursor position (for example, on a single row, rowset, before, or after the result table). Fetching stops when an error is returned, all requested rows are fetched, or the end of data condition is reached.

Fetching multiple rows of data can be done with scrollable or non-scrollable cursors. The operations used to define, open, and close a cursor used for fetching multiple rows of data are the same as for those used for single row FETCH statements.

If the BEFORE or AFTER option is specified, neither single-row-fetch or multiple-row-fetch can be specified.

FOR host-variable or integer-constant ROWS
host-variable or integer-constant is assigned to an integral value k. If a host variable is specified, it must be an exact numeric type with a scale of zero and must not include an indicator variable. Furthermore, k must be in the range, 0<k<=32767.

This clause must not be specified if a row-positioned fetch-orientation clause was specified. This clause must also not be specified for a cursor that is defined without rowset access.

If a rowset fetch orientation is specified and this clause is not specified, the number of rows in the resulting rowset is determined as follows:

  • If the most recent FETCH statement for this cursor was a rowset-positioned FETCH, the number of rows of the rowset is implicitly determined by the number of rows that was most recently specified (implicitly or explicitly) for this cursor.
  • When the most recent FETCH statement for this cursor was either FETCH BEFORE or FETCH AFTER and the most recent FETCH statement for this cursor prior to that was a rowset-positioned FETCH, the number of rows of the rowset is implicitly determined by the number of rows that were most recently specified (implicitly or explicitly) for this cursor.
  • Otherwise, the rowset consists of a single row.

For result set cursors, the number of rows for a rowset cursor position, established in the procedure that defined the rowset, is not inherited by the caller when the rowset is returned. Use the FOR n ROWS clause on the first rowset FETCH statement for the result set in the calling program to establish the number of rows for the cursor. Otherwise, the rowset consists of a single row.

The cursor is positioned on the row or rowset that is specified by the orientation clause (for example, NEXT ROWSET), and those rows are fetched if a target is specified. After the cursor is positioned on the first row being fetched, the next k-1 rows are fetched. Fetching moves forward from the cursor position in the result table and continues until the end of data condition is returned, k-1 rows have been fetched, or an assignment error is returned.

The resulting cursor position depends on the fetch orientation that is specified:

  • For a row-positioned fetch orientation, the cursor is positioned at the last row successfully retrieved.
  • For a rowset-positioned fetch orientation, the cursor is positioned on all the rows retrieved.

The values from each individual fetch are placed in data areas that are described in the INTO or USING clause. If a target specification is provided for a rowset-positioned FETCH, the host variable arrays must be specified as the target specification, and the arrays must be defined with a dimension of 1 or greater. The target specification must be defined as an array for a rowset-positioned FETCH even if the number of rows that is specified implicitly or explicitly is one. See Diagnostics information for rowset positioned FETCH statements.

INTO host-variable-array
Identifies for each column of the result table a host-variable-array to receive the data that is retrieved with this FETCH statement. If the number of host-variable-arrays is less than the number of columns of the result table, the SQLWARN3 field of the SQLCA is set to 'W'. No warning is given if there are more host-variable-arrays than the number of columns in the result table.

Each host-variable-array must be defined in the application program in accordance with the rules for declaring an array. A host-variable-array is used to return the values for a column of the result table. The number of rows to be fetched must be less than or equal to the dimension of each of the host-variable-arrays.

An optional indicator array can be specified for a host-variable-array. It should be specified if the SQLTYPE of any SQLVAR occurrence indicates that the column of the result table is nullable. Additionally, if an operation may result in null values, such as an UPDATE operation that results in a hole, is performed in the application, an indicator array should be specified. Otherwise an error occurs if null values are encountered. The indicators are returned as small integers.

INTO DESCRIPTOR descriptor-name
Identifies an SQLDA that must contain a valid description of zero or more host-variable-arrays or buffers into which the values for a column of the result table are to be returned.

Before the FETCH statement is processed, you must set the following fields in the SQLDA:

  • SQLN to indicate the number of SQLVAR occurrences provided in the SQLDA.
  • SQLABC to indicate the number of bytes of storage allocated for the SQLDA.
  • SQLD to indicate the number of variables used in the SQLDA when processing the statement.
  • SQLVAR occurrences to indicate the attributes of an element of the host-variable-array. Within each SQLVAR representing an array:
    • SQLTYPE indicates the data type of the elements of the host-variable-array.
    • SQLDATA field points to the first element of the host-variable-array.
    • The length fields (SQLLEN and SQLLONGLEN) are set to indicate the maximum length of a single element of the array.
    • SQLNAME - The length of SQLNAME must be set to 8, and the first two bytes of the data portion of SQLNAME must be initialized to X'0000'. The fifth and sixth bytes must contain a flag field and the seventh and eighth bytes must be initialized to a binary small integer (half word) representation of the dimension of the host-variable-array, and the corresponding indicator array, if one is specified.
    The SQLVAR entry for the number of rows must also contain a flag value. The number of rows to be fetched must be less than or equal to the dimension of each of the host variable arrays.

You set the SQLDATA and SQLIND pointers to the beginning of the corresponding arrays. The SQLDA must have enough storage to contain all SQLVAR occurrences. Each SQLVAR occurrence describes a host-variable-array or buffer into which the values for a column in the result table are to be returned. If any column of the result table is a LOB, two SQLVAR entries must be provided for each SQLVAR, and SQLN must be set to two times the number of SQLVARS. SQLD must be set to a value greater than or equal to zero and less than or equal to SQLN.

Notes

Assignment to host variables:
The nth variable identified by the INTO clause or described in the SQLDA corresponds to the nth column of the result table of the cursor. The data type of a host variable must be compatible with its corresponding value. If the value is numeric, the variable must have the capacity to represent the whole part of the value. For a datetime value, the variable must be a character string variable of a minimum length as defined in String representations of datetime values. If the value is null, an indicator variable must be specified.

Assignments are made in sequence through the list. Each assignment to a variable is made according to the rules described in Language elements. If the number of variables is less than the number of values in the row, the SQLWARN3 field of the SQLCA is set to W. There is no warning if there are more variables than the number of result columns. If the value is null, an indicator variable must be provided. If an assignment error occurs, the value is not assigned to the variable and no more values are assigned to variables. Any values that have already been assigned to variables remain assigned.

Normally, you use LOB locators to assign and retrieve data from LOB columns. However, because of compatibility rules, you can also use LOB locators to assign data to host variables with other data types. For more information on using locators, see Saving storage when manipulating LOBs by using LOB locators.

Start of changeThe default encoding scheme for the data is the value in the bind option ENCODING, which is the option for application encoding. If this statement is used with functions such as LENGTH or SUBSTRING that are operating on LOB locators, and the LOB data that is specifies by the locator is in a different encoding scheme from the ENCODING bind option, LOB materialization and character conversion occur. To avoid LOB materialization and character conversion, select the LOB data from the SYSIBM.SYSDUMMYA, SYSIBM.SYSDUMMYE, or SYSIBM.SYSDUMMYU sample table.End of change

Restrictions on using the WITH CONTINUE and CURRENT CONTINUE clauses:
When using the WITH CONTINUE clause, the DB2 system will only reserve truncated data for result set columns of the BLOB, CLOB, DBCLOB, or XML data type, and only when the output host variable data type is the appropriate LOB data type.

If an application uses FETCH WITH CONTINUE, and truncated data remains after the FETCH operation, the application cannot perform any intervening operation on that cursor before performing the FETCH CURRENT CONTINUE. If intervening operations on that cursor are performed, the truncated data is lost.

FETCH CURRENT CONTINUE is not supported with multi-row fetch. Also, FETCH CURRENT CONTINUE is not supported for non-LOB and non-XML columns that have been truncated. If truncation occurs for these non-LOB and non-XML columns, the truncated data will be discarded as usual.

Result column evaluation considerations:
If an error occurs as the result of an arithmetic expression in the SELECT list of an outer SELECT statement (division by zero, or overflow) or a numeric conversion error occurs, the result is the null value. As in any other case of a null value, an indicator variable must be provided and the main variable is unchanged. In this case, however, the indicator variable is set to -2. Processing of the statement continues as if the error had not occurred. (However, this error causes a positive SQLCODE.) If you do not provide an indicator variable, a negative value is returned in the SQLCODE field of the SQLCA. Processing of the statement terminates when the error is encountered. No value is assigned to the host variable or to later variables, though any values that have already been assigned to variables remain assigned.

If the specified host variable is not large enough to contain the result, a warning is returned and W is assigned to SQLWARN1 in the SQLCA. The actual length of the result is returned in the indicator variable associated with the host-variable, if an indicator is provided. It is possible that a warning may not be returned on a FETCH operation. This occurs as a result of optimizations, such as the use of system temporary tables or blocking. It is also possible that the returned warning applies to a previously fetched row. When a datetime value is returned, the length of the variable must be large enough to store the complete value. Otherwise, a warning or an error is returned.

Start of changeConsiderations when using the FETCH statement for a rowset cursor that was passed to an accelerator server for processing:End of change
Start of changeDB2 provides limited support for rowset queries that are passed to an accelerator server for processing. DB2 supports only high performance access to accelerated query data. The data is pre-fetched in rowsets and returned by using multiple-row-fetch statements, returning multiple rows of data in one FETCH statement. The following restrictions apply to FETCH statements that are executed against a rowset cursor that was accelerated:
  • All FETCH requests must be rowset fetches.
  • All FETCH requests must specify a FOR n ROWS clause.
  • All FETCH requests must specify the same rowset size.
  • All FETCH requests must specify target host variables. (The FETCH operation must have a target for positioning.)
End of change
Cursor positioning:
An open cursor has three possible positions:
  • Before a row
  • On a row or rowset
  • After the last row

When a scrollable or non-scrollable cursor is opened, it is positioned before the first row in the result table. If a cursor is on a row, that row is called the current row of the cursor. If a cursor is on a rowset, the rows are called the current rowset of the cursor.

A cursor referred to in an UPDATE or DELETE statement must be positioned on a row or rowset. A cursor can only be on a row or rowset as a result of a FETCH statement.

If the cursor was declared SENSITIVE STATIC SCROLL, a row may be a hole, from which no values may be fetched, updated, or deleted. Holes do not exist with sensitive dynamic cursors because there is no temporary result table. For information about holes in the result table of a cursor, see DB2 Application Programming and SQL Guide.

For scrollable cursors, the cursor position after an error varies depending on the type of error:

  • When an operation is attempted against an update or delete hole, or when an update or delete hole is detected, the cursor is positioned on the hole.
  • When a FETCH operation is attempted past the end of file, the cursor is positioned after the last row.
  • When a FETCH operation is attempted before the beginning of file, the cursor is positioned before the first row.
  • When an error causes the cursor position to be invalid such as when a single row positioned update or positioned delete error occurs that causes a rollback, the cursor is closed.
Cursor position after exception condition:
If an error occurs during the execution of a fetch operation, the position of the cursor and the result of any later fetch is unpredictable. It is possible for an error to occur that makes the position of the cursor invalid, in which case the cursor is closed.

If an individual fetch operation specifies a destination that is outside the range of the cursor, a warning is issued (except for FETCH BEFORE or FETCH AFTER), the cursor is positioned before or after the result table, and values are not assigned to host variables.

Concurrency and scrollability:
The current row of a cursor cannot be updated or deleted by another application process if it is locked. Unless it is already locked because it was inserted or updated by the application process during the current unit of work, the current row of a cursor is not locked if:
  • The isolation level is UR, or
  • The isolation level is CS, and
    • The result table of the cursor is read-only
    • The bind option CURRENTDATA(NO) is in effect

A dynamic scrollable cursor is useful when it is more important to the application to see updated rows and newly inserted rows and there is no need to see deleted rows. The isolation level of CS should be used for maximum concurrency with dynamic scrollable cursors. Specifying an isolation level of RR or RS severely restricts the update of the table, thus defeating the purpose of a SENSITIVE DYNAMIC scrollable cursor. If the application needs a constant result table, a SENSITIVE STATIC scrollable cursor with an isolation level of CS should be used.

Sensitivity of SENSITIVE STATIC SCROLL cursors to database changes:
When SENSITIVE STATIC SCROLL has been declared, the following rules apply:
  • For the result of an update operation to be visible within a cursor after "open," the update operation must be a positioned update executed against the cursor, or a FETCH SENSITIVE in a STATIC cursor must be executed against a row which has been updated by some other means (that is, a searched update, committed updates of others, or an update with another cursor in the same process).
  • Another process can update the base table of the SELECT statement so that the current values no longer satisfy the WHERE clause. In this case, an "update hole" effectively exists during the time the values in the base table do not satisfy the WHERE clause, and the row is no longer accessible through the cursor. When an attempt is made to fetch a row that has been identified as an update hole, no values are returned, and a warning is issued.

    Under SENSITIVE STATIC SCROLL cursors, update holes are only identified during positioned update, positioned delete, and FETCH SENSITIVE operations. Each positioned update, positioned delete, and FETCH SENSITIVE operation does the necessary tests to determine if an update hole exists.

  • For the result of a delete operation to be visible within a SENSITIVE STATIC SCROLL cursor, the delete operation must be a positioned delete executed against the cursor or a FETCH SENSITIVE in a STATIC cursor must be executed against a row that has been deleted by some other means (that is, a searched delete, committed deletes of others, or a delete with another cursor in the same process).
  • Another process, or the even the same process, may delete a row in the base table of the SELECT statement so that a row of the cursor no longer has a corresponding row in the base table. In this case, a "delete hole" effectively exists, and that row is no longer accessible through the cursor. When an attempt is made to fetch a row that has been identified as a delete hole, no values are returned, and a warning is issued.

    Under SENSITIVE STATIC SCROLL cursors, delete holes are identified during positioned update, positioned delete, and FETCH SENSITIVE operations.

  • Inserts into the base table or tables of SENSITIVE STATIC SCROLL cursors are not seen after the cursor is opened.
LOB locators:
When information is retrieved into LOB locators and it is not necessary to retain the locator across FETCH statements, it is a good practice to issue a FREE LOCATOR statement before issuing another FETCH statement because locator resources are limited.
Isolation level considerations:
The isolation level of the statement (specified implicitly or explicitly) can affect the result of a rowset-positioned FETCH statement. This is possible when changes are made to the tables underlying the cursor when isolation level UR is used with a dynamic scrollable cursor, or with other isolation levels when rows have been added by the application fetching from the cursor. These situations can occur with the following fetch orientations:
PRIOR ROWSET
With a dynamic scrollable cursor and isolation level UR, the content of a prior rowset can be affected by other activity within the table. It is possible that a row that previously qualified for the cursor, and was included as a member of the "prior" rowset, has since been deleted or modified before it is actually returned as part of the rowset for the current statement. To avoid this behavior, use an isolation level other than UR.
CURRENT ROWSET
With a dynamic scrollable cursor, additional rows can be added between rows that form the rowset that was returned to the user. With isolation level RR, these rows can only be added by the application fetching from the cursor. For isolation levels other than RR, other applications can insert rows that can affect the results of a subsequent FETCH CURRENT ROWSET. To avoid this behavior, use a static scrollable cursor instead of a dynamic scrollable cursor.
LAST ROWSET
With a dynamic scrollable cursor and isolation level UR, the content of the last rowset can be affected by other activity within the table. It is possible that a row that previously qualified for the cursor, and was included as a member of the "last" rowset, has since been deleted or modified before it is actually returned as part of the rowset for the current statement. To avoid this behavior, use an isolation level other than UR.
ROWSET STARTING AT RELATIVE -n (where -n is a negative number)
With a dynamic scrollable cursor and isolation level UR, the content of a prior rowset can be affected by other activity within the table. It is possible that a row that previously qualified for the cursor, and was included as a member of the "prior" rowset, has since been deleted or modified before it is actually returned as part of the rowset for the current statement. To avoid this behavior, use an isolation level other than UR.
Row positioned and rowset positioned FETCH statement interaction:
The following table demonstrates the interaction between row positioned and rowset positioned FETCH statements. The table is based on the following assumptions:
  • TABLE T1 has 15 rows
  • CURSOR CS1 is declared as follows:
    DECLARE CS1 SCROLL CURSOR WITH ROWSET POSITIONING FOR
    SELECT * FROM T1;
  • An OPEN CURSOR statement has been successfully executed for CURSOR CS1 and the FETCH statements in the table are executed in the order that they appear in the table.
Table 6. Interaction between row positioned and rowset positioned FETCH statements
FETCH Statement Cursor Position
FETCH FIRST Cursor is positioned on row 1.
FETCH FIRST ROWSET Cursor is positioned on a rowset of size 1, consisting of row 1.
FETCH FIRST ROWSET FOR 5 ROWS Cursor is positioned on a rowset of size 5, consisting of rows 1, 2, 3, 4, and 5.
FETCH CURRENT ROWSET Cursor is positioned on a rowset of size 5, consisting of rows 1, 2, 3, 4, and 5.
FETCH CURRENT Cursor is positioned on row 1
FETCH FIRST ROWSET FOR 5 ROWS Cursor is positioned on a rowset of size 5, consisting of rows 1, 2, 3, 4, and 5.
FETCH or FETCH NEXT Cursor is positioned on row 2.
FETCH NEXT ROWSET Cursor is positioned on a rowset of size 1, consisting of row 3.
FETCH NEXT ROWSET FOR 3 ROWS Cursor is positioned on a rowset of size 3, consisting of rows 4,5, and 6.
FETCH NEXT ROWSET Cursor is positioned on a rowset of size 3, consisting of rows 7,8, and 9.
FETCH LAST Cursor is positioned on row 15.
FETCH LAST ROWSET FOR 2 ROWS Cursor is positioned on a rowset of size 2, consisting of rows 14 and 15.
FETCH PRIOR ROWSET Cursor is positioned on a rowset of size 2, consisting of rows 12 and 13.
FETCH ABSOLUTE 2 Cursor is positioned on row 2.
FETCH ROWSET STARTING AT ABSOLUTE 2 FOR 3 ROWS Cursor is positioned on a rowset of size 3, consisting of rows 2, 3, and 4.
FETCH RELATIVE 2 Cursor is positioned on row 4.
FETCH ROWSET STARTING AT ABSOLUTE 2 FOR 4 ROWS Cursor is positioned on a rowset of size 4, consisting of rows 2, 3, 4, and 5.
FETCH RELATIVE -1 Cursor is positioned on row 1.
FETCH ROWSET STARTING AT ABSOLUTE 3 FOR 2 ROWS Cursor is positioned on a rowset of size 2, consisting of rows 3 and 4.
FETCH ROWSET STARTING AT RELATIVE 4 Cursor is positioned on a rowset of size 2, consisting of rows 7 and 8.
FETCH PRIOR Cursor is positioned on row 6.
FETCH ROWSET STARTING AT ABSOLUTE 13 FOR 5 ROWS Cursor is positioned on a rowset of size 3, consisting of rows 13, 14, and 15.
FETCH FIRST ROWSET Cursor is positioned on a rowset of size 5, consisting of rows 1, 2, 3, 4, and 5.
Note: Even though the previous FETCH statement returned only 3 rows because EOF was encountered, DB2 will remember that 5 rows were requested by the previous FETCH statement.
Considerations for using the FOR n ROWS clause with the FETCH FIRST n ROWS ONLY clause:
A clause specifying the number of rows that you want can be specified in the SELECT statement of a cursor, the FETCH statement for a cursor, or both. However, these clauses have different effects:
  • In the SELECT statement, a FETCH FIRST n ROWS ONLY clause controls the maximum number of rows that can be accessed with the cursor. When a FETCH statement attempts to retrieve a row beyond the number specified in the FETCH FIRST n ROWS ONLY clause of the SELECT statement, an end-of-data condition occurs.
  • In a FETCH statement, a FOR n ROWS clause controls the number of rows that are returned for a single FETCH statement.

Both of these clauses can be specified.

Diagnostics information for rowset positioned FETCH statements:
A single FETCH statement from a rowset cursor might encounter zero, one, or more conditions. If the current cursor position is not valid for the fetch orientation, a warning occurs and the statement terminates. If a warning or non-terminating error (such as a bind out error) occurs during the fetch of a row, processing continues. In this case, a summary message is returned for the FETCH statement, and additional information about each fetched row is available with the GET DIAGNOSTICS statement. Use the GET DIAGNOSTICS statement to obtain information about all of the conditions that are encountered for one of these FETCH statements. See GET DIAGNOSTICS for more information.
The SQLCA returns some information about errors and warnings that are found while fetching from a rowset cursor. Processing stops when the end of data is encountered, or when a terminating condition occurs. After each FETCH statement from a rowset cursor, information is returned to the program through the SQLCA. The SQLCA is set as follows:
  • SQLCODE contains the SQLCODE.
  • SQLSTATE contains the SQLSTATE.
  • SQLERRD1 and SQLERRD2 contain the number of rows of the result table if the cursor is positioned on the last row of the result table.
  • SQLERRD3 contains the actual number of rows returned. If SQLERRD3 is less than the number of rows requested, an error or end-of-data condition occurred.
  • SQLWARN flags are set to represent all the warnings that were accumulated while processing the FETCH statement.

Consider the following examples, where 10 rows are fetched with a single FETCH statement.

  • Example 1: Assume that an error is detected on the 5th row. SQLERRD3 is set to 4 for the 4 returned rows, SQLSTATE is set to 22537, and SQLCODE is set to -354. This information is also available from the GET DIAGNOSTICS statement (the information that is returned is generated from connected server, which may differ across different servers). For example:
    GET DIAGNOSTICS :num_rows = ROW_COUNT, :num_cond = NUMBER;
    -- Results of the statement: 
    -- num_rows = 4 and num_cond = 1 (1 condition)
    GET DIAGNOSTICS CONDITION 1 :sqlstate = RETURNED_SQLSTATE,
    :sqlcode = DB2_RETURNED_SQLCODE, :row_num = DB2_ROW_NUMBER;
    -- Results of the statement:
    -- sqlstate = 22537, sqlcode = -354, and row_num = 5
  • Example 2: Assume that an end-of-data condition is detected on the 6th row and that the cursor does not have immediate sensitivity to updates. SQLERRD3 is set to 5 for the 5 returned rows, SQLSTATE is set to 02000, and SQLCODE is set to +100. This information is also available from the GET DIAGNOSTICS statement. For example:
    GET DIAGNOSTICS :num_rows = ROW_COUNT, :num_cond = NUMBER;
    -- Results of the statement:
    -- num_rows = 5 and num_cond = 1 (1 condition)
    GET DIAGNOSTICS CONDITION 1 :sqlstate = RETURNED_SQLSTATE,
    :sqlcode = DB2_RETURNED_SQLCODE, :row_num = DB2_ROW_NUMBER;
    -- Results of the statement: 
    -- sqlstate = 02000, sqlcode = 100, and row_num = 6
  • Example 3: Assume that a bind error condition is detected on the 5th row, the condition is recorded, and processing continues. Also, assume that an end-of-data condition is detected on the 8th row. SQLERRD3 is set to 7 for the 7 returned rows, SQLSTATE is set to 02000, and SQLCODE is set to +100. Processing to complete the FETCH statement is performed, and the bind out error that occurred is noted. An additional SQLCODE is recorded for the bind out error. SQLCODE is set to –354, and SQLSTATE is set to 01668. Use the GET DIAGNOSTICS statement to determine what went on. For example:
    GET DIAGNOSTICS :num_rows = ROW_COUNT, :num_cond = NUMBER;
    -- Results of the statement:
    -- num_rows = 7 and num_cond = 3 (3 conditions)
    GET DIAGNOSTICS CONDITION 1 :sqlstate = RETURNED_SQLSTATE,
    :sqlcode = RETURNED_SQLCODE, :row_num = DB2_ROW_NUMBER;
    -- Results of the statement: 
    -- sqlstate = 01668, sqlcode = -354, and row_num = 0
    GET DIAGNOSTICS CONDITION 2 :sqlstate = RETURNED_SQLSTATE,
    :sqlcode = RETURNED_SQLCODE, :row_num = DB2_ROW_NUMBER;
    -- Results of the statement:
    -- sqlstate = 02000, sqlcode = 100, and row_num = 0
    GET DIAGNOSTICS CONDITION 3 :sqlstate = RETURNED_SQLSTATE,
    :sqlcode = RETURNED_SQLCODE, :row_num = DB2_ROW_NUMBER;
    -- Results of the statement:
    -- sqlstate = 22003, sqlcode = -302, and row_num = 5

In some cases, DB2 returns a warning if indicator variables are provided, or an error if indicator variables are not provided. These errors can be thought of as data mapping errors that result in a warning if indicator variables are provided.

  • If indicator variables are provided, DB2 returns all rows to the user, marking the errors in the indicator variables. The SQLCODE and SQLSTATE contain the warning from the last data mapping error. The GET DIAGNOSTICS statement can be used to retrieve information about all the data mapping errors that have occurred.
  • If some or no indicator variables are provided, all rows are returned as above until the first data mapping error that does not have indicator variables is detected. The rows successfully fetched are returned and the SQLSTATE, SQLCODE, and SQLWARN flags are set, if necessary. (The SQLCODE may be 0 or a positive value).

It is possible, if a data mapping error occurs, for the positioning of the cursor to be successful. In this case, the cursor is positioned on the rowset that encountered the data mapping error.

Consider the following examples, which try to fetch 10 rows with a single FETCH statement.

  • Example 1: Assume that indicators have been provided for values returned for column 1, but not for column 2. The 5th row has a data mapping error (+802) for column 1, and the 7th row has a data mapping error for column 2 (-802 is returned because an indicator was not provided for column 2). SQLERRD3 is set to 6 for the 6 returned rows, SQLSTATE and SQLCODE are set to the error from the 7th row fetched. The indicator variable for the 5th row column 1 indicates that a data mapping error was found. This information is also available from the GET DIAGNOSTICS statement, for example:
    GET DIAGNOSTICS :num_rows = ROW_COUNT, :num_cond = NUMBER;
    -- Results of the statement:
    -- num_rows = 6 and num_cond = 2 (2 conditions)
    GET DIAGNOSTICS CONDITION 1 :sqlstate = RETURNED_SQLSTATE,
    :sqlcode = DB2_RETURNED_SQLCODE, :row_num = DB2_ROW_NUMBER;
    -- Results of the statement: 
    -- sqlstate = 01519, sqlcode = +802, and row_num = 5
    GET DIAGNOSTICS CONDITION 2 :sqlstate = RETURNED_SQLSTATE,
    :sqlcode = DB2_RETURNED_SQLCODE, :row_num = DB2_ROW_NUMBER;
    -- Results of the statement:
    -- sqlstate = 22003, sqlcode = -802, and row_num = 7
    The resulting cursor position is unknown.
  • Example 2: Assume that null indicators are provided, that rows 3 and 5 are holes, and that data exists for the other requested rows. SQLERRD3 is set to 10 to reflect that 10 fetches were completed and that information has been returned for the 10 requested rows. Eight rows actually contain data. For two rows, indicator variables are set to indicate no data was returned for those rows. SQLSTATE is set to 02502, SQLCODE is set to +222, and all null indicators for rows 3 and 5 are set to -3 to indicate that a hole was detected. This information is also available from the GET DIAGNOSTICS statement, for example:
    GET DIAGNOSTICS :num_rows = ROW_COUNT, :num_cond = NUMBER;
    -- Results of the statement: 
    -- num_rows = 10 and num_cond = 2 (2 conditions)
    GET DIAGNOSTICS CONDITION 1 :sqlstate = RETURNED_SQLSTATE, 
    :sqlcode = DB2_RETURNED_SQLCODE, :row_num = DB2_ROW_NUMBER;
    -- Results of the statement: 
    -- sqlstate = 02502, sqlcode = +222, and row_num = 3
    GET DIAGNOSTICS CONDITION 2 :sqlstate = RETURNED_SQLSTATE,
    :sqlcode = DB2_RETURNED_SQLCODE, :row_num = DB2_ROW_NUMBER;
    -- Results of the statement: 
    -- sqlstate = 02502, sqlcode = +222, and row_num = 5
    If a null indicator was not provided for any variable in a row that was a hole, an error occurs.
SQLCA usage summary:
For multiple-row-fetch, the fields of the SQLCA are set as follows:
Condition Action: Resulting Values Stored in the SQLCA Fields
Errors Data SQLSTATE SQLCODE SQLERRD3
No1 Return all requested rows 00000 0 Number of rows requested
No1 Return data for subset of requested rows, end of data 02000 +100 Number of rows rows
No1 Return all requested rows sqlstate(2) sqlcode(2) Number of rows requested
Yes1 Return successfully fetched rows sqlstate(3) sqlcode(3) Number of rows
Yes1 Return successfully fetched rows sqlstate(4) sqlcode(4) Number of rows
Notes:
  1. SQLWARN flags may be set in all cases, even if there are no other warnings or errors indicated. The warning flags are an accumulation of all warning flags set while processing the multiple-row-fetch.
  2. sqlcode is the last positive SQLCODE, and sqlstate is the corresponding SQLSTATE value.
  3. Database Server detected error. sqlcode is the first negative SQLCODE encountered, sqlstate is the corresponding SQLSTATE value.
  4. Client detected error. sqlcode is the first negative SQLCODE encountered, sqlstate is one of the following SQLSTATEs: 22002, 22008, 22509, 22518, or 55021.
Providing indicator variables for error conditions:
If an error occurs as the result of an arithmetic expression in the SELECT list of an outer SELECT statement (division by zero or overflow) or a numeric conversion error occurs, the result is the null value. As in any other case of a null value, an indicator variable must be provided and the main variable is unchanged. In this case, however, the indicator variable is set to -2. Processing of the statement continues as if the error had not occurred. (However, this error causes a positive SQLCODE.)

If you do not provide an indicator variable, a negative value is returned in the SQLCODE field of the SQLCA. Processing of the statement terminates when the error is encountered. No value is assigned to the host variable or to later variables, though any values that have already been assigned to variables remain assigned. Additionally, a -3 is returned in all indicators provided by the application when a hole was detected for the row on a rowset positioned FETCH, and values were not returned for the row. Processing of the statement terminates if a hole is detected and at least one indicator variable was not provided by the application.

Alternative syntax and synonyms:
USING DESCRIPTOR can be specified as a synonym for INTO DESCRIPTOR.

Example

Example 1: The FETCH statement fetches the results of the SELECT statement into the application program variables DNUM, DNAME, and MNUM. When no more rows remain to be fetched, the not found condition is returned.
   EXEC SQL DECLARE C1 CURSOR FOR
     SELECT DEPTNO, DEPTNAME, MGRNO FROM DSN8A10.DEPT
     WHERE ADMRDEPT = 'A00';
    EXEC SQL OPEN C1;
    DO WHILE (SQLCODE = 0);
     EXEC SQL FETCH C1 INTO :DNUM, :DNAME, :MNUM;
    END;
    EXEC SQL CLOSE C1;

Example 2: For an example of FETCH statements with a dynamic scrollable cursor, see Example 8.

Example 3: Fetch the last 5 rows of the result table C1 using cursor C1:
FETCH ROWSET STARTING AT ABSOLUTE -5 
   FROM C1 FOR 5 ROWS INTO DESCRIPTOR :MYDESCR;
Example 4: Fetch 6 rows starting at row 10 for cursor CURS1, and fetch the data into three host-variable-arrays:
FETCH ROWSET STARTING AT ABSOLUTE 10
   FROM CURS1 FOR 6 ROWS
   INTO :hav1, :hva2, :hva3;
Alternatively, a descriptor could have been specified in an INTO DESCRIPTOR clause where the information in the SQLDA reflects the data types of the host-variable-arrays:
FETCH ROWSET STARTING AT ABSOLUTE 10
   FROM CURS1 FOR 6 ROWS
   INTO DESCRIPTOR :MYDESCR; 
1 ASSEMBLER and other languages are supported, but this support is limited to statements that allow USING DESCRIPTOR. The precompiler does not recognize host-variable-arrays except in C/C++, COBOL, and PL/I.