Contents|Index|Previous|Next

SQLFetchScroll

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 non-blank 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.
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 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).”

Positioning the Cursor

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.

Cursor Positioning Rules

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.

SQL_FETCH_NEXT

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.

SQL_FETCH_PRIOR

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]
CurrRowsetStartRowsetSize [2]
After end AND LastResultRow < RowsetSize [2]
1 [1]
After end AND LastResultRow >= RowsetSize [2]
LastResultRowRowsetSize + 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.

SQL_FETCH_RELATIVE

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.

SQL_FETCH_ABSOLUTE

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 an absolute fetch on a static cursor is.

SQL_FETCH_FIRST

The following rules apply.

Condition
First row of new rowset



Any
1

SQL_FETCH_LAST

The following rules apply.

Condition
First row of new rowset



RowsetSize [1] <= LastResultRow
LastResultRowRowsetSize + 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.

SQL_FETCH_BOOKMARK

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).”

Effect of Deleted, Added, and Error Rows on Cursor Movement

Static and keyset-driven cursors sometimes detect rows added to the result set and remove rows deleted from the result set. An application determines whether the cursors implemented by a particular driver do this 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. 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.

Returning Data in Bound Columns

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.

Buffer Addresses

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.

Row Status Array

SQLFetchScroll sets values in the row status array in the same manner as SQLFetch. For more information, see “Row Status Array” in SQLFetch.

Rows Fetched Buffer

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.

Error Handling

When an application calls SQLFetchScroll in an ODBC 3.0 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.0 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:

odbc00090000.gif When a warning occurs that applies to a particular row in the rowset, SQLExtendedFetch sets the corresponding entry in the row status array to SQL_ROW_SUCCESS, not SQL_ROW_SUCCESS_WITH_INFO.

odbc00090000.gif If errors occur in every row in the rowset, SQLExtendedFetch returns SQL_SUCCESS_WITH_INFO, not SQL_ERROR.

odbc00090000.gif In each group of status records that applies to an individual row, the first status record returned by SQLExtendedFetch must contain SQLSTATE 01S01 (Error in row); SQLFetchScroll does not return this SQLSTATE. Note that if SQLExtendedFetch is unable to return additional SQLSTATEs, it still must return this SQLSTATE.

SQLFetchScroll and Optimistic Concurrency

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).

SQLFetchScroll and ODBC 2.x Drivers

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.”

Descriptors and SQLFetchScroll

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