IRowset::GetNextRows
Fetches rows sequentially, remembering the previous position.
IRowset::GetNextRows fetches a sequence of rows. The provider maintains a next fetch position that is used in subsequent calls to either IRowset::GetNextRows or IRowsetFind::FindNextRow. The next fetch position is changed either by calling IRowset::GetNextRows or by calling IRowsetFind::FindNextRow with a null pBookmark value. Calling IRowsetFind::FindNextRow with a non-null pBookmark value has no effect on the next fetch position. If the fetch direction is reversed from the previous call, the next fetch position in the new direction is the last row that was fetched in the previous direction. Otherwise, the next fetch position is the row following the last row fetched by IRowset::GetNextRows or by IRowsetFind::FindNextRow with a null pBookmark value.
For any rowset except a newly created rowset (or an existing rowset on which IRowset::RestartPosition has been called and before the consumer has fetched any rows), IRowset::GetNextRows or IRowsetFind::FindNextRow may adjust the next fetch position, until the end of the rowset (or the beginning, if DBPROP_CANSCROLLBACKWARDS is VARIANT_TRUE) is reached. After the end of the rowset is reached, calls to IRowset::GetNextRows or IRowsetFind::FindNextRow return DB_S_ENDOFROWSET. (Earlier 1.x providers may return DB_E_BADSTARTPOSITION.)
IRowset::RestartPosition is used to reset the next fetch position to its initial state — that is, its state when the rowset was first created.
For a newly created rowset (or a rowset on which IRowset::RestartPosition has been called and before the consumer has fetched any rows), the next fetch position is computed as follows, where N is the number of rows in the rowset. lRowsOffset can be less than zero only if DBPROP_CANSCROLLBACKWARDS is VARIANT_TRUE.
|
Value of lRowsOffset |
Value of cRows |
Initial next fetch position |
|---|---|---|
|
lRowsOffset > 0 |
cRows is not zero |
After lRowsOffset |
|
lRowsOffset < 0 |
cRows is not zero |
After N – abs(lRowsOffset) |
|
lRowsOffset = 0 |
cRows > 0 |
Before first row |
|
lRowsOffset = 0 |
cRows < 0 |
After last row |
The following table shows the row fetched and the resulting next fetch position when IRowset::GetNextRows is called with various positive and negative values of lRowsOffset and cRows. Assume the rowset contains five rows.
Note
|
|---|
|
For each IRowset::GetNextRows call in the first column, the second and third columns show the result when the call is made to a newly created rowset (or a rowset on which IRowset::RestartPosition has been called and before the consumer has fetched any rows). |
|
If the first call to IRowset::GetNextRows is: |
Row fetched |
Resulting next fetch position |
|---|---|---|
GetNextRows(hReserved, 2, 1, pcRowsObtained, prghRows); |
3rd row |
After 3rd row |
GetNextRows(hReserved, 2, -1, pcRowsObtained, prghRows); |
2nd row |
Before 2nd row |
GetNextRows(hReserved, -2, 1, pcRowsObtained, prghRows); |
4th row |
After 4th row |
GetNextRows(hReserved, -2, -1, pcRowsObtained, prghRows); |
3rd row |
Before 3rd row |
GetNextRows(hReserved, 0, 1, pcRowsObtained, prghRows); |
1st row |
After 1st row |
GetNextRows(hReserved, 0, -1, pcRowsObtained, prghRows); |
5th row |
Before 5th row |
The following example shows how the next fetch position is affected by a series of consecutive calls to IRowset::GetNextRows, beginning with a newly created rowset (or a rowset on which IRowset::RestartPosition has been called and before the consumer has fetched any rows) that contains six rows and has DBPROP_CANSCROLLBACKWARDS set to VARIANT_TRUE.
Note
|
|---|
|
An error will occur if the row fetched or next fetch position specified is beyond the range of the rowset. |
|
Series of IRowset::GetNextRows calls |
Row(s) fetched |
New next fetch position |
|---|---|---|
GetNextRows(hReserved, 0, 1, pcRowsObtained, prghRows); |
1st row |
After 1st row |
GetNextRows(hReserved, 1, 3, pcRowsObtained, prghRows); |
3rd, 4th, and 5th rows |
After 5th row |
GetNextRows(hReserved, -2, -1, pcRowsObtained, prghRows); |
3rd row |
Before 3rd row |
GetNextRows(hReserved, 0, -1, pcRowsObtained, prghRows); |
2nd row |
Before 2nd row |
GetNextRows(hReserved, -1, 2, pcRowsObtained, prghRows); |
1st and 2nd rows |
After 2nd row |
GetNextRows(hReserved, 4, -1, pcRowsObtained, prghRows); |
6th row |
Before 6th row |
GetNextRows(hReserved, -2, 1, pcRowsObtained, prghRows); |
4th row |
After 4th row |
None of the other methods that fetch rows, except for IRowsetFind::FindNextRow with a null pBookmark value, has any effect on the next fetch position. However, IRowsetIndex::Seek sets the next fetch position to the row specified in the seek criteria, and IRowset::RestartPosition resets the next fetch position to the same position as when the rowset is first created.
IRowset::GetNextRows increments, by 1, the reference count of each row for which it returns a handle. Therefore, if a handle is returned for a row that has already been fetched, the reference count of that row will be greater than 1. IRowset::ReleaseRows must be called once for each time the handle to a row has been returned.
If the provider encounters a problem fetching a row — for example, data stored in a text file contains a letter in a numeric column — IRowset::GetNextRows fetches the row normally, returns the row handle, and returns S_OK. However, when the consumer calls IRowset::GetData for the row, the provider returns DBSTATUS_E_CANTCONVERTVALUE as the status for the offending column.
Before changing the next fetch position, IRowset::GetNextRows must always check for the conditions that cause E_INVALIDARG, E_UNEXPECTED, DB_E_CANTFETCHBACKWARDS, DB_E_CANTSCROLLBACKWARDS, DB_E_NOTREENTRANT, and DB_E_ROWSNOTRELEASED. If it returns any other error besides these, the next fetch position is unknown. For example, the provider might have to perform actions that change the next fetch position in order to determine that the error DB_E_BADSTARTPOSITION occurred. When the next fetch position is unknown, the consumer usually calls IRowset::RestartPosition to return it to a known position.
Whether a provider returns DB_S_ENDOFROWSET, DB_S_ROWLIMITEXCEEDED, or DB_S_STOPLIMITREACHED generally depends on which limit is encountered first. If the maximum number of row handles is obtained before trying to read past the rowset or beyond a resource limit, DB_S_ROWLIMITEXCEEDED is returned. If a resource limitation is reached when there are still row handles available and before attempting to read past the rowset, DB_S_STOPLIMITREACHED is returned. If the provider comes to the end of the rowset before using all of the available row handles and before reaching a resource limitation, DB_S_ENDOFROWSET is returned.
For information about what IRowset::GetNextRows does when it fetches a row that already exists in its internal buffers, see Uniqueness of Rows in the Rowset. For information about whether IRowset::GetNextRows can detect changes made to rows in the rowset, see Visibility of Changes.
Note