Call Level Interface Guide and Reference

SQLSetPos - Set the Cursor Position in a Rowset

Purpose


Specification: DB2 CLI 5.0 ODBC 1  

SQLSetPos() sets the cursor position in a rowset.

Syntax

SQLRETURN   SQLSetPos        (SQLHSTMT          StatementHandle,
                              SQLUSMALLINT      RowNumber,
                              SQLUSMALLINT      Operation,
                              SQLUSMALLINT      LockType);

Function Arguments

Table 166. SQLSetPos Arguments
Data Type Argument Use Description
SQLHSTMT StatementHandle input Statement handle.
SQLUSMALLINT RowNumber input

Position of the row in the rowset on which to perform the operation specified with the Operation argument. If RowNumber is 0, the operation applies to every row in the rowset.

For additional information, see RowNumber Argument.

SQLUSMALLINT Operation input Operation to perform:
  • SQL_POSITION
  • SQL_REFRESH
  • SQL_UPDATE
  • SQL_DELETE
  • SQL_ADD

For additional information, see Operation Argument.

ODBC also specifies the following operations for backwards compatibility only, which DB2 CLI also supports:

  • SQL_ADD

While DB2 CLI does support SQL_ADD in SQLSetPos() calls, it is suggested that you use SQLBulkOperations() with the Operation argument set to SQL_ADD. See SQLBulkOperations - Add, Update, Delete or Fetch a Set of Rows for more information.

SQLUSMALLINT LockType input Specifies how to lock the row after performing the operation specified in the Operation argument.
  • SQL_LOCK_NO_CHANGE
ODBC also specifies the following operations which DB2 CLI does not support:
  • SQL_LOCK_EXCLUSIVE
  • SQL_LOCK_UNLOCK
For additional information, see LockType Argument.

Usage

RowNumber Argument

The RowNumber argument specifies the number of the row in the rowset on which to perform the operation specified by the Operation argument. If RowNumber is 0, the operation applies to every row in the rowset. RowNumber must be a value from 0 to the number of rows in the rowset.

Note In the C language, arrays are 0-based, while the RowNumber argument is 1-based. For example, to update the fifth row of the rowset, an application modifies the rowset buffers at array index 4, but specifies an RowNumber of 5.

All operations position the cursor on the row specified by RowNumber. The following operations require a cursor position:

An application can specify a cursor position when it calls SQLSetPos(). Generally, it calls SQLSetPos() with the SQL_POSITION or SQL_REFRESH operation to position the cursor before executing a positioned update or delete statement or calling SQLGetData().

Operation Argument

To determine which options are supported by a data source, an application calls SQLGetInfo() with one of the following information types, depending on the type of cursor:

SQL_POSITION

DB2 CLI positions the cursor on the row specified by RowNumber.

The contents of the row status array pointed to by the SQL_ATTR_ROW_OPERATION_PTR statement attribute are ignored for the SQL_POISTION Operation.

SQL_REFRESH

DB2 CLI positions the cursor on the row specified by RowNumber and refreshes data in the rowset buffers for that row. For more information about how DB2 CLI returns data in the rowset buffers, see the descriptions of row-wise and column-wise binding in SQLFetchScroll().

SQLSetPos() with an Operation of SQL_REFRESH simply updates the status and content of the rows within the current fetched rowset. This includes refreshing the bookmarks. The data in the buffers is refreshed, but not refetched, so the membership in the rowset is fixed.

A successful refresh with SQLSetPos() will not change a row status of SQL_ROW_DELETED. Deleted rows within the rowset will continue to be marked as deleted until the next fetch. The rows will disappear at the next fetch if the cursor supports packing (in which case a subsequent SQLFetch() or SQLFetchScroll() does not return deleted rows).

A successful refresh with SQLSetPos() will change a row status of SQL_ROW_ADDED to SQL_ROW_SUCCESS (if the row status array exists).

A refresh with SQLSetPos() will change a row status of SQL_ROW_UPDATED to the row's new status (if the row status array exists).

If an error occurs in a SQLSetPos() operation on a row, the row status is set to SQL_ROW_ERROR (if the row status array exists).

For a cursor opened with a SQL_ATTR_CONCURRENCY statement attribute of SQL_CONCUR_ROWVER or SQL_CONCUR_VALUES, a refresh with SQLSetPos() will update the optimistic concurrency values used by the data source to detect that the row has changed. This occurs for each row that is refreshed.

The contents of the row status array are ignored for the SQL_REFRESH Operation.

SQL_UPDATE

DB2 CLI positions the cursor on the row specified by RowNumber and updates the underlying row of data with the values in the rowset buffers (the TargetValuePtr argument in SQLBindCol()). It retrieves the lengths of the data from the length/indicator buffers (the StrLen_or_IndPtr argument in SQLBindCol()). If the length of any column is SQL_COLUMN_IGNORE, the column is not updated. After updating the row, the corresponding element of the row status array is updated to SQL_ROW_UPDATED or SQL_ROW_SUCCESS_WITH_INFO (if the row status array exists).

The row operation array pointed to by the SQL_ATTR_ROW_OPERATION_PTR statement attribute can be used to indicate that a row in the current rowset should be ignored during a bulk update. For more information, see Status and Operation Arrays.

SQL_DELETE

DB2 CLI positions the cursor on the row specified by RowNumber and deletes the underlying row of data. It changes the corresponding element of the row status array to SQL_ROW_DELETED. After the row has been deleted, the following are not valid for the row:

Deleted rows remain visible to static and keyset-driven cursors; however, the entry in the implementation row status array (pointed to by the SQL_ATTR_ROW_STATUS_PTR statement attribute) for the deleted row is changed to SQL_ROW_DELETED.

The row operation array pointed to by the SQL_ATTR_ROW_OPERATION_PTR statement attribute can be used to indicate that a row in the current rowset should be ignored during a bulk delete. For more information, see Status and Operation Arrays.

SQL_ADD

ODBC also specifies the SQL_ADD Operation for backwards compatibility only, which DB2 CLI also supports. It is suggested, however, that you use SQLBulkOperations() with the Operation argument set to SQL_ADD.

See SQLBulkOperations - Add, Update, Delete or Fetch a Set of Rows for more information.

LockType Argument

The LockType argument provides a way for applications to control concurrency. Generally, data sources that support concurrency levels and transactions will only support the SQL_LOCK_NO_CHANGE value of the LockType argument.

Although the LockType argument is specified for a single statement, the lock accords the same privileges to all statements on the connection. In particular, a lock that is acquired by one statement on a connection can be unlocked by a different statement on the same connection.

ODBC defines the following LockType arguments. DB2 CLI supports SQL_LOCK_NO_CHANGE. To determine which locks are supported by a data source, an application calls SQLGetInfo() with the SQL_LOCK_TYPES information type.

Table 167. Operation Values
LockType Argument Lock Type
SQL_LOCK_NO_CHANGE Ensures that the row is in the same locked or unlocked state as it was before SQLSetPos() was called. This value of LockType allows data sources that do not support explicit row-level locking to use whatever locking is required by the current concurrency and transaction isolation levels.
SQL_LOCK_EXCLUSIVE Not supported by DB2 CLI. Locks the row exclusively.
SQL_LOCK_UNLOCK Not supported by DB2 CLI. Unlocks the row.

Status and Operation Arrays

The following status and operation arrays are used when calling SQLSetPos():

The number of elements in the status and operation arrays must equal the number of rows in the rowset (as defined by the SQL_ATTR_ROW_ARRAY_SIZE statement attribute).

For information about the row status array, see SQLFetch - Fetch Next Row.

Return Codes

Diagnostics

Table 168. SQLSetPos SQLSTATEs
SQLSTATE Description Explanation
01000 Warning. Informational message. (Function returns SQL_SUCCESS_WITH_INFO.)
01004 Data truncated. The Operation argument was SQL_REFRESH, and string or binary data returned for a column or columns with a data type of SQL_C_CHAR or SQL_C_BINARY resulted in the truncation of non-blank character or non-NULL binary data
01S01 Error in row. The RowNumber argument was 0 and an error occurred in one or more rows while performing the operation specified with the Operation argument.

(SQL_SUCCESS_WITH_INFO is returned if an error occurs on one or more, but not all, rows of a multirow operation, and SQL_ERROR is returned if an error occurs on a single-row operation.)

01S07 Fractional truncation. The Operation argument was SQL_REFRESH, the data type of the application buffer was not SQL_C_CHAR or SQL_C_BINARY, and the data returned to application buffers for one or more columns was truncated. For numeric data types, the fractional part of the number was truncated. For time and timestamp data types, the fractional portion of the time was truncated.
07006 Invalid conversion. The data value of a column in the result set could not be converted to the data type specified by TargetType in the call to SQLBindCol().
07009 Invalid descriptor index. The argument Operation was SQL_REFRESH or SQL_UPDATE and a column was bound with a column number greater than the number of columns in the result set.
21S02 Degrees of derived table does not match column list. The argument Operation was SQL_UPDATE and no columns were updateable because all columns were either unbound, read-only, or the value in the bound length/indicator buffer was SQL_COLUMN_IGNORE.
22001 String data right truncation. The assignment of a character or binary value to a column resulted in the truncation of non-blank (for characters) or non-null (for binary)characters or bytes.
22003 Numeric value out of range. The argument Operation was SQL_UPDATE and the assignment of a numeric value to a column in the result set caused the whole (as opposed to fractional) part of the number to be truncated.

The argument Operation was SQL_REFRESH, and returning the numeric value for one or more bound columns would have caused a loss of significant digits.

22007 Invalid datetime format. The argument Operation was SQL_UPDATE, and the assignment of a date or timestamp value to a column in the result set caused the year, month, or day field to be out of range.

The argument Operation was SQL_REFRESH, and returning the date or timestamp value for one or more bound columns would have caused the year, month, or day field to be out of range.

22008 Datetime field overflow. The Operation argument was SQL_UPDATE, and the performance of datetime arithmetic on data being sent to a column in the result set resulted in a datetime field (the year, month, day, hour, minute, or second field) of the result being outside the permissible range of values for the field, or being invalid based on the natural rules for datetimes based on the Gregorian calendar.

The Operation argument was SQL_REFRESH, and the performance of datetime arithmetic on data being retrieved from the result set resulted in a datetime field (the year, month, day, hour, minute, or second field) of the result being outside the permissible range of values for the field, or being invalid based on the natural rules for datetimes based on the Gregorian calendar.

HY000 General error. An error occurred for which there was no specific SQLSTATE. The error message returned by SQLGetDiagRec() in the *MessageText buffer describes the error and its cause.
HY001 Memory allocation failure. DB2 CLI was unable to allocate memory required to support execution or completion of the function.
HY008 Operation was cancelled

Asynchronous processing was enabled for the StatementHandle. The function was called and before it completed execution, SQLCancel() was called on the StatementHandle. Then the function was called again on the StatementHandle.

The function was called and, before it completed execution, SQLCancel() was called on the StatementHandle from a different thread in a multithread application.

HY010 Function sequence error. The specified StatementHandle was not in an executed state. The function was called without first calling SQLExecDirect(), SQLExecute(), or a catalog function.

An asynchronously executing function (not this one) was called for the StatementHandle and was still executing when this function was called.

SQLExecute(), SQLExecDirect(), or SQLSetPos() was called for the StatementHandle and returned SQL_NEED_DATA. This function was called before data was sent for all data-at-execution parameters or columns.

A Version 2 DB2 CLI application called SQLSetPos() for a StatementHandle before SQLFetchScroll() was called or after SQLFetch() was called, and before SQLFreeStmt() was called with the SQL_CLOSE option.

HY011 Operation invalid at this time. A Version 2 DB2 CLI application set the SQL_ATTR_ROW_STATUS_PTR statement attribute; then SQLSetPos() was called before SQLFetch(), SQLFetchScroll(), or SQLExtendedFetch() was called.
HY090 Invalid string or buffer length. The Operation argument was SQL_ADD, SQL_UPDATE, or SQL_UPDATE_BY_BOOKMARK, a data value was a null pointer, and the column length value was not 0, SQL_DATA_AT_EXEC, SQL_COLUMN_IGNORE, SQL_NULL_DATA, or less than or equal to SQL_LEN_DATA_AT_EXEC_OFFSET.

The Operation argument was SQL_ADD, SQL_UPDATE, or SQL_UPDATE_BY_BOOKMARK, a data value was not a null pointer, and the column length value was less than 0, but not equal to SQL_DATA_AT_EXEC, SQL_COLUMN_IGNORE, SQL_NTS, or SQL_NULL_DATA, or less than or equal to SQL_LEN_DATA_AT_EXEC_OFFSET.

A value in a length/indicator buffer was SQL_DATA_AT_EXEC; the SQL type was either SQL_LONGVARCHAR, SQL_LONGVARBINARY, or a other, data-source-specific data type; and the SQL_NEED_LONG_DATA_LEN information type in SQLGetInfo() was "Y".

HY092 Option type out of range. The Operation argument was SQL_UPDATE_BY_BOOKMARK, SQL_DELETE_BY_BOOKMARK, or SQL_REFRESH_BY_BOOKMARK, and the SQL_ATTR_USE_BOOKMARKS statement attribute was set to SQL_UB_OFF.
HY107 Row value out of range. The value specified for the argument RowNumber was greater than the number of rows in the rowset.
HY109 Invalid cursor position. The cursor associated with the StatementHandle was defined as forward only, so the cursor could not be positioned within the rowset. See the description for the SQL_ATTR_CURSOR_TYPE attribute in SQLSetStmtAttr().

The Operation argument was SQL_UPDATE, SQL_DELETE, or SQL_REFRESH, and the row identified by the RowNumber argument had been deleted or had not be fetched.

The RowNumber argument was 0 and the Operation argument was SQL_POSITION.

HYC00 Driver not capable. DB2 CLI or the data source does not support the operation requested in the Operation argument or the LockType argument.
HYT00 Timeout expired The query timeout period expired before the data source returned the result set. The timeout period is set through SQLSetStmtAttr() with an Attribute of SQL_ATTR_QUERY_TIMEOUT.

Restrictions

None.

CLI Sample tbread.c

(The complete sample tbread.c is also available here .)

 
/* From the CLI sample TBREAD.C */
/* ... */
 
    sqlrc = SQLSetPos( hstmt, 3, SQL_POSITION, SQL_LOCK_NO_CHANGE); 
    STMT_HANDLE_CHECK( hstmt, sqlrc);    
    sqlrc = SQLGetData(hstmt, 0, SQL_C_LONG, bookmark.val, 4, &bookmark.ind);
    STMT_HANDLE_CHECK( hstmt, sqlrc);    
    sqlrc = SQLSetStmtAttr( hstmt,
                         SQL_ATTR_FETCH_BOOKMARK_PTR, 
                         (SQLPOINTER) bookmark.val, 
                         0);
    STMT_HANDLE_CHECK( hstmt, sqlrc); 
    
/* ... */
 
    sqlrc = SQLSetPos( hstmt, 3, SQL_POSITION, SQL_LOCK_NO_CHANGE); 
    STMT_HANDLE_CHECK( hstmt, sqlrc);    
    sqlrc = SQLGetData(hstmt, 0, SQL_C_LONG, bookmark.val, 4, &bookmark.ind);
    STMT_HANDLE_CHECK( hstmt, sqlrc);    
    sqlrc = SQLSetStmtAttr( hstmt,
                         SQL_ATTR_FETCH_BOOKMARK_PTR, 
                         (SQLPOINTER) bookmark.val, 
                         0);
    STMT_HANDLE_CHECK( hstmt, sqlrc); 
    
 

References


[ Top of Page | Previous Page | Next Page ]