MDAC 2.5 SDK - ODBC Programmer's Reference
Chapter 21: ODBC API Reference
Conformance
Version Introduced: ODBC 3.0
Standards Compliance: ISO 92
Summary
SQLFetchScroll fetches the specified rowset of data from the result set and returns data for all bound columns. Rowsets can be specified at an absolute or relative position or by bookmark.
When working with an ODBC 2.x driver, the Driver Manager maps this function to SQLExtendedFetch. For more information, see "Mapping Replacement Functions for Backward Compatibility of Applications" in Chapter 17, "Programming Considerations."
Syntax
SQLRETURN SQLFetchScroll(
SQLHSTMT StatementHandle,
SQLSMALLINT FetchOrientation,
SQLINTEGER FetchOffset);
Arguments
StatementHandle
[Input]
Statement handle.
FetchOrientation
[Input]
Type of fetch:
SQL_FETCH_NEXT
SQL_FETCH_PRIOR
SQL_FETCH_FIRST
SQL_FETCH_LAST
SQL_FETCH_ABSOLUTE
SQL_FETCH_RELATIVE
SQL_FETCH_BOOKMARK
For more information, see "Positioning the Cursor" in the "Comments" section.
FetchOffset
[Input]
Number of the row to fetch. The interpretation of this argument depends on the value of the FetchOrientation argument. For more information, see "Positioning the Cursor" in the "Comments" section.
Returns
SQL_SUCCESS, SQL_SUCCESS_WITH_INFO, SQL_NO_DATA, SQL_STILL_EXECUTING, SQL_ERROR, or SQL_INVALID_HANDLE.
Diagnostics
When SQLFetchScroll returns either SQL_ERROR or SQL_SUCCESS_WITH_INFO, an associated SQLSTATE value can be obtained by calling SQLGetDiagRec with a HandleType of SQL_HANDLE_STMT and a Handle of StatementHandle. The following table lists the SQLSTATE values commonly returned by SQLFetchScroll and explains each one in the context of this function; the notation "(DM)" precedes the descriptions of SQLSTATEs returned by the Driver Manager. The return code associated with each SQLSTATE value is SQL_ERROR, unless noted otherwise. If an error occurs on a single column, SQLGetDiagField can be called with a DiagIdentifier of SQL_DIAG_COLUMN_NUMBER to determine the column the error occurred on; and SQLGetDiagField can be called with a DiagIdentifier of SQL_DIAG_ROW_NUMBER to determine the row containing that column.
For all those SQLSTATEs that can return SQL_SUCCESS_WITH_INFO or SQL_ERROR (except 01xxx SQLSTATEs), 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.
SQLSTATE | Error | Description |
01000 | General warning | Driver-specific informational message. (Function returns SQL_SUCCESS_WITH_INFO.) |
01004 | String data, right truncated | String or binary data returned for a column resulted in the truncation of nonblank character or non-NULL binary data. String values are right-truncated. |
01S01 | Error in row | An error occurred while fetching one or more rows.
(This SQLSTATE is returned only by ODBC 2.x drivers.) |
01S06 | Attempt to fetch before the result set returned the first rowset | The requested rowset overlapped the start of the result set when FetchOrientation was SQL_FETCH_PRIOR, the current position was beyond the first row, and the number of the current row is less than or equal to the rowset size.
The requested rowset overlapped the start of the result set when FetchOrientation was SQL_FETCH_PRIOR, the current position was beyond the end of the result set, and the rowset size was greater than the result set size. The requested rowset overlapped the start of the result set when FetchOrientation was SQL_FETCH_RELATIVE, FetchOffset was negative, and the absolute value of FetchOffset was less than or equal to the rowset size. The requested rowset overlapped the start of the result set when FetchOrientation was SQL_FETCH_ABSOLUTE, FetchOffset was negative, and the absolute value of FetchOffset was greater than the result set size but less than or equal to the rowset size. (Function returns SQL_SUCCESS_WITH_INFO.) |
01S07 | Fractional truncation | The data returned for a column was truncated. For numeric data types, the fractional part of the number was truncated. For time, timestamp, and interval data types containing a time component, the fractional portion of the time was truncated.
(Function returns SQL_SUCCESS_WITH_INFO.) |
07006 | Restricted data type attribute violation | A data value of a column in the result set could not be converted to the C data type specified by TargetType in SQLBindCol.
Column 0 was bound with a data type of SQL_C_BOOKMARK, and the SQL_ATTR_USE_BOOKMARKS statement attribute was set to SQL_UB_VARIABLE. Column 0 was bound with a data type of SQL_C_VARBOOKMARK, and the SQL_ATTR_USE_BOOKMARKS statement attribute was not set to SQL_UB_VARIABLE. |
07009 | Invalid descriptor index | Column 0 was bound, and the SQL_ATTR_USE_BOOKMARKS statement attribute was set to SQL_UB_OFF. |
08S01 | Communication link failure | The communication link between the driver and the data source to which the driver was connected failed before the function completed processing. |
22001 | String data, right truncation | A variable-length bookmark returned for a row was truncated. |
22002 | Indicator variable required but not supplied | NULL data was fetched into a column whose StrLen_or_IndPtr set by SQLBindCol (or SQL_DESC_INDICATOR_PTR set by SQLSetDescField or SQLSetDescRec) was a null pointer. |
22003 | Numeric value out of range | Returning the numeric value (as numeric or string) for one or more bound columns would have caused the whole (as opposed to fractional) part of the number to be truncated.
For more information, see Guidelines for Interval and Numeric Data Types in Appendix D, "Data Types." |
22007 | Invalid datetime format | A character column in the result set was bound to a date, time, or timestamp C structure, and a value in the column was, respectively, an invalid date, time, or timestamp. |
22012 | Division by zero | A value from an arithmetic expression was returned, which resulted in division by zero. |
22015 | Interval field overflow | Assigning from an exact numeric or interval SQL type to an interval C type caused a loss of significant digits in the leading field.
When fetching data to an interval C type, there was no representation of the value of the SQL type in the interval C type. |
22018 | Invalid character value for cast specification | A character column in the result set was bound to a character C buffer, and the column contained a character for which there was no representation in the character set of the buffer.
The C type was an exact or approximate numeric, a datetime, or an interval data type; the SQL type of the column was a character data type; and the value in the column was not a valid literal of the bound C type. |
24000 | Invalid cursor state | The StatementHandle was in an executed state, but no result set was associated with the StatementHandle. |
40001 | Serialization failure | The transaction in which the fetch was executed was terminated to prevent deadlock. |
40003 | Statement completion unknown | The associated connection failed during the execution of this function, and the state of the transaction cannot be determined. |
HY000 | General error | An error occurred for which there was no specific SQLSTATE and for which no implementation-specific SQLSTATE was defined. The error message returned by SQLGetDiagRec in the *MessageText buffer describes the error and its cause. |
HY001 | Memory allocation error |
The driver was unable to allocate memory required to support execution or completion of the function. |
HY008 | Operation canceled | 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 | (DM) The specified StatementHandle was not in an executed state. The function was called without first calling SQLExecDirect, SQLExecute, or a catalog function.
(DM) An asynchronously executing function (not this one) was called for the StatementHandle and was still executing when this function was called. (DM) SQLExecute, SQLExecDirect, SQLBulkOperations, 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. (DM) SQLFetchScroll was called for a StatementHandle after SQLExtendedFetch was called and before SQLFreeStmt with SQL_CLOSE was called. |
HY013 | Memory management error | The function call could not be processed because the underlying memory objects could not be accessed, possibly because of low memory conditions. |
HY090 | Invalid string or buffer length | The SQL_ATTR_USE_BOOKMARK statement attribute was set to SQL_UB_VARIABLE, and column 0 was bound to a buffer whose length was not equal to the maximum length for the bookmark for this result set. (This length is available in the SQL_DESC_OCTET_LENGTH field of the IRD and can be obtained by calling SQLDescribeCol, SQLColAttribute, or SQLGetDescField.) |
HY106 | Fetch type out of range | (DM) The value specified for the argument FetchOrientation was invalid.
(DM) The argument FetchOrientation was SQL_FETCH_BOOKMARK, and the SQL_ATTR_USE_BOOKMARKS statement attribute was set to SQL_UB_OFF. The value of the SQL_ATTR_CURSOR_TYPE statement attribute was SQL_CURSOR_FORWARD_ONLY, and the value of argument FetchOrientation was not SQL_FETCH_NEXT. The value of the SQL_ATTR_CURSOR_SCROLLABLE statement attribute was SQL_NONSCROLLABLE, and the value of argument FetchOrientation was not SQL_FETCH_NEXT. |
HY107 | Row value out of range | The value specified with the SQL_ATTR_CURSOR_TYPE statement attribute was SQL_CURSOR_KEYSET_DRIVEN, but the value specified with the SQL_ATTR_KEYSET_SIZE statement attribute was greater than 0 and less than the value specified with the SQL_ATTR_ROW_ARRAY_SIZE statement attribute. |
HY111 | Invalid bookmark value | The argument FetchOrientation was SQL_FETCH_BOOKMARK, and the bookmark pointed to by the value in the SQL_ATTR_FETCH_BOOKMARK_PTR statement attribute was not valid or was a null pointer. |
HYC00 | Optional feature not implemented | Driver or data source does not support the specified fetch type.
The driver or data source does not support the conversion specified by the combination of the TargetType in SQLBindCol and the SQL data type of the corresponding column. FetchOrientation was SQL_FETCH_BOOKMARK, FetchOffset was not equal to 0, and the underlying driver is an ODBC 2.x driver. |
HYT01 | Connection timeout expired | The connection timeout period expired before the data source responded to the request. The connection timeout period is set through SQLSetConnectAttr, SQL_ATTR_CONNECTION_TIMEOUT. |
IM001 | Driver does not support this function | (DM) The driver associated with the StatementHandle does not support the function. |
Comments
SQLFetchScroll returns a specified rowset from the result set. Rowsets can be specified by absolute or relative position or by bookmark. SQLFetchScroll can be called only while a result set exists—that is, after a call that creates a result set and before the cursor over that result set is closed. If any columns are bound, it returns the data in those columns. If the application has specified a pointer to a row status array or a buffer in which to return the number of rows fetched, SQLFetchScroll returns this information as well. Calls to SQLFetchScroll can be mixed with calls to SQLFetch but cannot be mixed with calls to SQLExtendedFetch.
For more information, see "Using Block Cursors" and "Using Scrollable Cursors" in Chapter 11, "Retrieving Results (Advanced)."
When the result set is created, the cursor is positioned before the start of the result set. SQLFetchScroll positions the block cursor based on the values of the FetchOrientation and FetchOffset arguments as shown in the following table. The exact rules for determining the start of the new rowset are shown in the next section.
FetchOrientation | Meaning |
SQL_FETCH_NEXT | Return the next rowset. This is equivalent to calling SQLFetch.
SQLFetchScroll ignores the value of FetchOffset. |
SQL_FETCH_PRIOR | Return the prior rowset.
SQLFetchScroll ignores the value of FetchOffset. |
SQL_FETCH_RELATIVE | Return the rowset FetchOffset from the start of the current rowset. |
SQL_FETCH_ABSOLUTE | Return the rowset starting at row FetchOffset. |
SQL_FETCH_FIRST | Return the first rowset in the result set.
SQLFetchScroll ignores the value of FetchOffset. |
SQL_FETCH_LAST | Return the last complete rowset in the result set.
SQLFetchScroll ignores the value of FetchOffset. |
SQL_FETCH_BOOKMARK | Return the rowset FetchOffset rows from the bookmark specified by the SQL_ATTR_FETCH_BOOKMARK_PTR statement attribute. |
Drivers are not required to support all fetch orientations; an application calls SQLGetInfo with an information type of SQL_DYNAMIC_CURSOR_ATTRIBUTES1, SQL_KEYSET_CURSOR_ATTRIBUTES1, or SQL_STATIC_CURSOR_ATTRIBUTES1 (depending on the type of the cursor) to determine which fetch orientations are supported by the driver. The application should look at the SQL_CA1_NEXT, SQL_CA1_RELATIVE, SQL_CA1_ABSOLUTE, and WQL_CA1_BOOKMARK bitmasks in these information types. Furthermore, if the cursor is forward-only and FetchOrientation is not SQL_FETCH_NEXT, SQLFetchScroll returns SQLSTATE HY106 (Fetch type out of range).
The SQL_ATTR_ROW_ARRAY_SIZE statement attribute specifies the number of rows in the rowset. If the rowset being fetched by SQLFetchScroll overlaps the end of the result set, SQLFetchScroll returns a partial rowset. That is, if S + R – 1 is greater than L, where S is the starting row of the rowset being fetched, R is the rowset size, and L is the last row in the result set, then only the first L – S + 1 rows of the rowset are valid. The remaining rows are empty and have a status of SQL_ROW_NOROW.
After SQLFetchScroll returns, the current row is the first row of the rowset.
The following sections describe the exact rules for each value of FetchOrientation. These rules use the following notation.
Notation | Meaning |
Before start | The block cursor is positioned before the start of the result set. If the first row of the new rowset is before the start of the result set, SQLFetchScroll returns SQL_NO_DATA. |
After end | The block cursor is positioned after the end of the result set. If the first row of the new rowset is after the end of the result set, SQLFetchScroll returns SQL_NO_DATA. |
CurrRowsetStart | The number of the first row in the current rowset. |
LastResultRow | The number of the last row in the result set. |
RowsetSize | The rowset size. |
FetchOffset | The value of the FetchOffset argument. |
BookmarkRow | The row corresponding to the bookmark specified by the SQL_ATTR_FETCH_BOOKMARK_PTR statement attribute. |
The following rules apply.
Condition | First row of new rowset |
Before start | 1 |
CurrRowsetStart + RowsetSize[1] <= LastResultRow | CurrRowsetStart + RowsetSize[1] |
CurrRowsetStart + RowsetSize[1]> LastResultRow | After end |
After end | After end |
[1] If the rowset size has been changed since the previous call to fetch rows, this is the rowset size that was used with the previous call.
The following rules apply.
Condition | First row of new rowset |
Before start | Before start |
CurrRowsetStart = 1 | Before start |
1 < CurrRowsetStart <= RowsetSize[2] | 1[1] |
CurrRowsetStart > RowsetSize[2] | CurrRowsetStart – RowsetSize[2] |
After end AND LastResultRow < RowsetSize[2] | 1[1] |
After end AND LastResultRow >= RowsetSize[2] | LastResultRow – RowsetSize + 1[2] |
[1] SQLFetchScroll returns SQLSTATE 01S06 (Attempt to fetch before the result set returned the first rowset) and SQL_SUCCESS_WITH_INFO.
[2] If the rowset size has been changed since the previous call to fetch rows, this is the new rowset size.
The following rules apply.
Condition | First row of new rowset |
(Before start AND FetchOffset > 0) OR (After end AND FetchOffset < 0) |
--[1] |
BeforeStart AND FetchOffset <= 0 | Before start |
CurrRowsetStart = 1 AND FetchOffset < 0 | Before start |
CurrRowsetStart > 1 AND CurrRowsetStart + FetchOffset < 1 AND | FetchOffset | > RowsetSize[3] |
Before start |
CurrRowsetStart > 1 AND CurrRowsetStart + FetchOffset < 1 AND | FetchOffset | <= RowsetSize[3] |
1[2] |
1 <= CurrRowsetStart + FetchOffset <= LastResultRow | CurrRowsetStart + FetchOffset |
CurrRowsetStart + FetchOffset > LastResultRow | After end |
After end AND FetchOffset >= 0 | After end |
[1] SQLFetchScroll returns the same rowset as if it was called with FetchOrientation set to SQL_FETCH_ABSOLUTE. For more information, see the "SQL_FETCH_ABSOLUTE" section.
[2] SQLFetchScroll returns SQLSTATE 01S06 (Attempt to fetch before the result set returned the first rowset) and SQL_SUCCESS_WITH_INFO.
[3] If the rowset size has been changed since the previous call to fetch rows, this is the new rowset size.
The following rules apply.
Condition | First row of new rowset |
FetchOffset < 0 AND | FetchOffset | <= LastResultRow |
LastResultRow + FetchOffset + 1 |
FetchOffset < 0 AND | FetchOffset | > LastResultRow AND | FetchOffset | > RowsetSize[2] |
Before start |
FetchOffset < 0 AND | FetchOffset | > LastResultRow AND | FetchOffset | <= RowsetSize[2] |
1[1] |
FetchOffset = 0 | Before start |
1 <= FetchOffset <= LastResultRow | FetchOffset |
FetchOffset > LastResultRow | After end |
[1] SQLFetchScroll returns SQLSTATE 01S06 (Attempt to fetch before the result set returned the first rowset) and SQL_SUCCESS_WITH_INFO.
[2] If the rowset size has been changed since the previous call to fetch rows, this is the new rowset size.
An absolute fetch performed against a dynamic cursor cannot provide the required result because row positions in a dynamic cursor are undetermined. Such an operation is equivalent to a fetch first followed by a fetch relative; it is not an atomic operation, as is an absolute fetch on a static cursor.
The following rules apply.
Condition | First row of new rowset |
Any | 1 |
The following rules apply.
Condition | First row of new rowset |
RowsetSize [1] <= LastResultRow | LastResultRow – RowsetSize + 1[1] |
RowsetSize [1] > LastResultRow | 1 |
[1] If the rowset size has been changed since the previous call to fetch rows, this is the new rowset size.
The following rules apply.
Condition | First row of new rowset |
BookmarkRow + FetchOffset < 1 | Before start |
1 <= BookmarkRow + FetchOffset <= LastResultRow | BookmarkRow + FetchOffset |
BookmarkRow + FetchOffset > LastResultRow | After end |
For information about bookmarks, see the "Bookmarks" section in Chapter 11, "Retrieving Results (Advanced)."
Static and keyset-driven cursors sometimes detect rows added to the result set and remove rows deleted from the result set. By calling SQLGetInfo with the SQL_STATIC_CURSOR_ATTRIBUTES2 and SQL_KEYSET_CURSOR_ATTRIBUTES2 options and looking at the SQL_CA2_SENSITIVITY_ADDITIONS, SQL_CA2_SENSITIVITY_DELETIONS, and SQL_CA2_SENSITIVITY_UPDATES bitmasks, an application determines whether the cursors implemented by a particular driver do this. For drivers that can detect deleted rows and remove them, the following paragraphs describe the effects of this behavior. For drivers that can detect deleted rows but cannot remove them, deletions have no effect on cursor movements, and the following paragraphs do not apply.
If the cursor detects rows added to the result set or removes rows deleted from the result set, it appears as if it detects these changes only when it fetches data. This includes the case when SQLFetchScroll is called with FetchOrientation set to SQL_FETCH_RELATIVE and FetchOffset set to 0 to refetch the same rowset, but does not include the case when SQLSetPos is called with fOption set to SQL_REFRESH. In the latter case, the data in the rowset buffers is refreshed, but not refetched, and deleted rows are not removed from the result set. Thus, when a row is deleted from or inserted into the current rowset, the cursor does not modify the rowset buffers. Instead, it detects the change when it fetches any rowset that previously included the deleted row or now includes the inserted row.
For example:
// Fetch the next rowset.
SQLFetchScroll(hstmt, SQL_FETCH_NEXT, 0);
// Delete third row of the rowset. Does not modify the rowset buffers.
SQLSetPos(hstmt, 3, SQL_DELETE, SQL_LOCK_NO_CHANGE);
// The third row has a status of SQL_ROW_DELETED after this call.
SQLSetPos(hstmt, 3, SQL_REFRESH, SQL_LOCK_NO_CHANGE);
// Refetch the same rowset. The third row is removed, replaced by what
// was previously the fourth row.
SQLFetchScroll(hstmt, SQL_FETCH_RELATIVE, 0);
When SQLFetchScroll returns a new rowset that has a position relative to the current rowset—that is, FetchOrientation is SQL_FETCH_NEXT, SQL_FETCH_PRIOR, or SQL_FETCH_RELATIVE—it does not include changes to the current rowset when calculating the starting position of the new rowset. However, it does include changes outside the current rowset if it is capable of detecting them. Furthermore, when SQLFetchScroll returns a new rowset that has a position independent of the current rowset—that is, FetchOrientation is SQL_FETCH_FIRST, SQL_FETCH_LAST, SQL_FETCH_ABSOLUTE, or SQL_FETCH_BOOKMARK—it includes all changes it is capable of detecting, even if they are in the current rowset.
When determining whether newly added rows are inside or outside the current rowset, a partial rowset is considered to end at the last valid row; that is, the last row for which the row status is not SQL_ROW_NOROW. For example, suppose the cursor is capable of detecting newly added rows, the current rowset is a partial rowset, the application adds new rows, and the cursor adds these rows to the end of the result set. If the application calls SQLFetchScroll with FetchOrientation set to SQL_FETCH_NEXT, SQLFetchScroll returns the rowset starting with the first newly added row.
For example, suppose the current rowset comprises rows 21 to 30, the rowset size is 10, the cursor removes rows deleted from the result set, and the cursor detects rows added to the result set. The following table shows the rows SQLFetchScroll returns in various situations.
Change | Fetch type | FetchOffset | New rowset[1] |
Delete row 21 | NEXT | 0 | 31 to 40 |
Delete row 31 | NEXT | 0 | 32 to 41 |
Insert row between rows 21 and 22 | NEXT | 0 | 31 to 40 |
Insert row between rows 30 and 31 | NEXT | 0 | Inserted row, 31 to 39 |
Delete row 21 | PRIOR | 0 | 11 to 20 |
Delete row 20 | PRIOR | 0 | 10 to 19 |
Insert row between rows 21 and 22 | PRIOR | 0 | 11 to 20 |
Insert row between rows 20 and 21 | PRIOR | 0 | 12 to 20, inserted row |
Delete row 21 | RELATIVE | 0 | 22 to 31[2] |
Delete row 21 | RELATIVE | 1 | 22 to 31 |
Insert row between rows 21 and 22 | RELATIVE | 0 | 21, inserted row, 22 to 29 |
Insert row between rows 21 and 22 | RELATIVE | 1 | 22 to 31 |
Delete row 21 | ABSOLUTE | 21 | 22 to 31[2] |
Delete row 22 | ABSOLUTE | 21 | 21, 23 to 31 |
Insert row between rows 21 and 22 | ABSOLUTE | 22 | Inserted row, 22 to 29 |
[1] This column uses the row numbers before any rows were inserted or deleted.
[2] In this case, the cursor attempts to return rows starting with row 21. Because row 21 has been deleted, the first row it returns is row 22.
Error rows (that is, rows with a status of SQL_ROW_ERROR) do not affect cursor movement. For example, if the current rowset starts with row 11 and the status of row 11 is SQL_ROW_ERROR, calling SQLFetchScroll with FetchOrientation set to SQL_FETCH_RELATIVE and FetchOffset set to 5 returns the rowset starting with row 16, just as it would if the status for row 11 was SQL_SUCCESS.
SQLFetchScroll returns data in bound columns in the same way as SQLFetch. For more information, see "Returning Data in Bound Columns" in SQLFetch.
If no columns are bound, SQLFetchScroll does not return data but does move the block cursor to the specified position. Whether data can be retrieved from unbound columns of a block cursor with SQLGetData depends on the driver. This capability is supported if a call to SQLGetInfo returns the SQL_GD_BLOCK bit for the SQL_GETDATA_EXTENSIONS information type.
SQLFetchScroll uses the same formula to determine the address of data and length/indicator buffers as SQLFetch. For more information, see "Buffer Addresses" in SQLBindCol.
SQLFetchScroll sets values in the row status array in the same manner as SQLFetch. For more information, see "Row Status Array" in SQLFetch.
SQLFetchScroll returns the number of rows fetched in the rows fetched buffer in the same manner as SQLFetch. For more information, see "Rows Fetched Buffer" in SQLFetch.
When an application calls SQLFetchScroll in an ODBC 3.x driver, the Driver Manager calls SQLFetchScroll in the driver. When an application calls SQLFetchScroll in an ODBC 2.x driver, the Driver Manager calls SQLExtendedFetch in the driver. Because SQLFetchScroll and SQLExtendedFetch handle errors in a slightly different manner, the application sees slightly different error behavior when it calls SQLFetchScroll in ODBC 2.x and ODBC 3.x drivers.
SQLFetchScroll returns errors and warnings in the same manner as SQLFetch; for more information, see "Error Handling" in SQLFetch. SQLExtendedFetch returns errors in the same manner as SQLFetch, with the following exceptions:
If a cursor uses optimistic concurrency—that is, the SQL_ATTR_CONCURRENCY statement attribute has a value of SQL_CONCUR_VALUES or SQL_CONCUR_ROWVER—SQLFetchScroll updates the optimistic concurrency values used by the data source to detect whether a row has changed. This happens whenever SQLFetchScroll fetches a new rowset, including when it refetches the current rowset. (It is called with FetchOrientation set to SQL_FETCH_RELATIVE and FetchOffset set to 0.)
When an application calls SQLFetchScroll in an ODBC 2.x driver, the Driver Manager maps this call to SQLExtendedFetch. It passes the following values for the arguments of SQLExtendedFetch.
SQLExtendedFetch argument |
Value |
StatementHandle | StatementHandle in SQLFetchScroll. |
FetchOrientation | FetchOrientation in SQLFetchScroll. |
FetchOffset | If FetchOrientation is not SQL_FETCH_BOOKMARK, the value of the FetchOffset argument in SQLFetchScroll is used.
If FetchOrientation is SQL_FETCH_BOOKMARK, the value stored at the address specified by the SQL_ATTR_FETCH_BOOKMARK_PTR statement attribute is used. |
RowCountPtr | The address specified by the SQL_ATTR_ROWS_FETCHED_PTR statement attribute. |
RowStatusArray | The address specified by the SQL_ATTR_ROW_STATUS_PTR statement attribute. |
For more information, see "Block Cursors, Scrollable Cursors, and Backward Compatibility" in Appendix G, "Driver Guidelines for Backward Compatibility."
SQLFetchScroll interacts with descriptors in the same manner as SQLFetch. For more information, see the "Descriptors and SQLFetchScroll" section in SQLFetch.
Code Example
See "Column-Wise Binding" and "Row-Wise Binding" in Chapter 11, "Retrieving Results (Advanced)", and "Positioned Update and Delete Statements" and "Updating Rows in the Rowset with SQLSetPos" in Chapter 12, "Updating Data."
Related Functions
For information about | See |
Binding a buffer to a column in a result set | SQLBindCol |
Performing bulk insert, update, or delete operations | SQLBulkOperations |
Canceling statement processing | SQLCancel |
Returning information about a column in a result set | SQLDescribeCol |
Executing an SQL statement | SQLExecDirect |
Executing a prepared SQL statement | SQLExecute |
Fetching a single row or a block of data in a forward-only direction | SQLFetch |
Closing the cursor on the statement | SQLFreeStmt |
Returning the number of result set columns | SQLNumResultCols |
Positioning the cursor, refreshing data in the rowset, or updating or deleting data in the result set | SQLSetPos |
Setting a statement attribute | SQLSetStmtAttr |