IRowsetFind::FindNextRow

Begins at the specified bookmark and finds the next row matching the specified value. IRowsetFind does not affect the next fetch position used by IRowset::GetNextRows.

HRESULT FindNextRow (
HCHAPTER                  hChapter,
HACCESSOR               hAccessor,
void *                        pFindValue,
DBCOMPAREOP            CompareOp,
ULONG                     cbBookmark,
const BYTE *               pBookmark,
BOOL                        fSkipCurrent,
LONG                        cRows,
ULONG *                     pcRowsObtained,
HROW **                     prghRows);

Parameters

hChapter [in]

The chapter handle. For nonchaptered rowsets, hChapter is ignored. If this is the first time the chapter is used, the chapter is opened and a reference count is taken to hold the chapter’s state. This reference count is released by calling ReleaseChapter.

hAccessor [in]

Accessor describing the value to be matched. This accessor must describe only a single column. If it describes more than one column, FindNextRow returns DB_E_BADBINDINFO. Valid coercions for FindNextRow are the same as those for SetData.

pFindValue[in]

Pointer to the value to be matched. If this value is NULL, it is compared to other values according to the DBPROP_NULLCOLLATION property returned in the Data Source Information property set.

CompareOp [in]

Operation to use in comparing the row values.

cbBookmark [in]

Length in bytes of the bookmark, or zero to start from the last row found by IRowsetFind.

pBookmark [in]

Pointer to a bookmark that identifies the row from which to start searching for a match. The consumer is not required to have access rights to this row. However, if this row matches the seek criteria, the provider cannot return it unless the consumer has read permission for it. The consumer can specify a cbBookmark value of zero, and set pBookmark to null, to request that the find occur starting with the last row found by IRowsetFind. If cRows was greater than 1, this is different than the last row returned by IRowsetFind. Thus, forward-only cursors that support IRowsetFind return E_INVALIDARG if cRows is greater than 1. If this is the first time IRowsetFind has been called on the rowset, specifying a null bookmark starts at the beginning of the rowset. If the rowset does not support IRowsetLocate, only the special bookmarks DBBMK_FIRST and DBBMK_LAST, and the null value, can be used. If the rowset does not support scrolling backward, only the null bookmark value can be used. If the rowset is chaptered, the identified row must fall within the specified chapter.

fSkipCurrent [in]

Whether or not to try and match the current row. If FALSE, the current row is compared and, if it matches the criteria, returned. If TRUE, the comparison starts at the first row following the current row in the direction indicated by cRows.

cRows [in]

The number of rows to fetch from the rowset, starting with the first row found. A negative number indicates a backward fetch. Check the DBPROP_CANFETCHBACKWARDS property returned in IRowsetInfo::GetProperties to determine whether this is supported. The search direction is the same as the fetch direction, so a negative count searches backward from the starting position and returns successively earlier rows as subsequent obtained rows. If cRows is zero and there are no other errors, no rows are fetched, but the fetch position for FindNextRow is moved to the next match or off the end of the rowset if no match is found.

pcRowsObtained [out]

A pointer to memory in which to return the actual number of fetched rows.

prghRows [out]

A pointer to memory in which to return an array of handles of the retrieved rows. If *prghRows is not a null pointer on input, it must be a pointer to memory large enough to return the handles of the requested number of rows. If *prghRows is a null pointer on input, the rowset allocates memory for the row handles and returns the address to this memory; the consumer releases this memory with IMalloc::Free after it releases the row handles. If *prghRows was a null pointer on input and *pcRowsObtained is zero on output, the provider does not allocate any memory and ensures that *prghRows is a null pointer on output.

Return Code

S_OK

The method succeeded.

DB_S_ENDOFROWSET

FindNextRow reached the start or the end of the rowset or (in a hierarchical rowset) the start or the end of the chapter, and could not fetch all requested rows because the count extended beyond the end. The next fetch position is before the start or after the end of the rowset. The number of rows actually returned is returned in *pcRowsObtained; this will be less than cRows.

DB_S_ROWLIMITEXCEEDED

Fetching the number of rows specified in cRows would have exceeded the total number of active rows supported by the rowset. The number of rows that were actually fetched is returned in *pcRowsObtained. This condition can occur only when there are more rows available than can be handled by the rowset. Thus, this condition never conflicts with those described in DB_S_ENDOFROWSET and DB_S_STOPLIMITREACHED, both of which imply that no more rows were available.

DB_S_STOPLIMITREACHED

Returning rows requires further execution of the command, such as when the rowset uses a server-side cursor. Execution has been stopped because a resource limit has been reached. The number of rows that were actually fetched is returned in *pcRowsObtained. Execution cannot be resumed.

DB_S_BOOKMARKSKIPPED

The following behavior is supported only on rowsets that set the DBPROP_BOOKMARKSKIPPED property to VARIANT_TRUE. If this property is VARIANT_FALSE, this return code is never returned. The row specified by *pBookmark was deleted, is no longer a member of the rowset, or is a row to which the consumer does not have access rights. FindNextRow skipped that row and began searching with the next row in the direction indicated by cRows. If this condition occurs along with another warning condition, the method returns the code for the other warning condition. Thus, whenever a consumer receives the return code for another warning condition, it should check to see if this condition occurred.

E_FAIL

A provider-specific error occurred.

E_INVALIDARG

pcRowsObtained or prghRows was a null pointer. cbBookmark was not zero and pBookmark was a null pointer.

E_OUTOFMEMORY

The provider was unable to allocate sufficient memory in which to create instances of the rows or return the row handles.

E_UNEXPECTED

ITransaction::Commit or ITransaction::Abort was called and the object is in a zombie state.

DB_E_BADBINDINFO

The specified accessor specified binding information for more than one column.

DB_E_BADBOOKMARK

*pBookmark was invalid; for example, it was incorrectly formed. *pBookmark did not match any rows in the rowset (this includes the case when the row corresponding to the bookmark has been deleted). The rowset was chaptered and *pBookmark did not apply to the specified chapter.

DB_E_BADCHAPTER

The rowset was chaptered and hChapter was invalid. The rowset was single chaptered and the specified chapter was not the open chapter. The consumer must use the open chapter or release the open chapter before specifying a new chapter.

DB_E_BADCOMPAREOP

CompareOp was an invalid value. CompareOp was DBCOMPAREOPS_BEGINSWITH or DBCOMPAREOPS_CONTAINS and pFindValue was not bound as a string value.

DB_E_CANTFETCHBACKWARDS

cRows was negative and the rowset cannot fetch backward.

DB_E_CANTSCROLLBACKWARDS

A bookmark value of DBBMK_FIRST or DBBMK_LAST was specified and the rowset cannot scroll backward. cRows was greater than 1 and the rowset is forward-only.

DB_E_NOTREENTRANT

The consumer called this method while it was processing a notification, and it is an error to call this method while processing the specified DBREASON value.

DB_E_ROWSNOTRELEASED

The provider requires release of prior HROWs before new ones can be obtained (see IDBPropertyInfo::GetPropertyInfo, DBPROP_CANHOLDROWS).

DB_SEC_E_PERMISSIONDENIED

The consumer did not have sufficient permission to get the rows.

Comments

See IRowsetLocate::GetRowsAt for a complete description of the results for given values for a bookmark, offset, and number of rows to fetch.

FindNextRow searches the rowset in the direction indicated by cRows for a row that matches pFindValue according to the specified CompareOp. Once a match is found, if cRows is greater than 1, additional rows are returned in rowset order as if the consumer called GetNextRows starting with the first matching row. If no rows match the criteria, FindNextRow returns DB_S_ENDOFROWSET and pcRowsObtained is set to zero.

When passing a null bookmark value to FindNextRow, the provider starts from the last row found, not from the last row returned, by FindNextRow. This allows the consumer to search for values within the last set of rows returned.

The rowset does not have to be ordered on the column searched. FindNextRow always finds the next row according to the criteria, regardless of the sort order.

FindNextRow increments by one the reference count of each row for which it returns a handle. Thus, if a handle is returned for a row that has already been fetched, the reference count of that row will be greater than 1. 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—FindNextRow fetches the row normally, returns the row handle, and returns S_OK. However, when the consumer calls GetData for the row, the provider returns DBSTATUS_E_CANTCONVERTVALUE as the status for the offending column.

FindNextRow 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 before changing the next fetch position. If it returns any other error, the next fetch position is unknown. For example, the provider might have to perform actions that change the next fetch position to determine that the error DB_E_BADSTARTPOSITION occurred. When the next fetch position is unknown, the consumer usually calls RestartPosition to return it to a known position.

For information about the actions of FindNextRow when it fetches a row that it already has in its internal buffers, see “Uniqueness of Rows in the Rowset” in Chapter 4 of the OLE DB Programmer’s Reference. For information about whether FindNextRow can detect changes made to rows in the rowset, see “Visibility of Changes” in Chapter 5 in the same reference.

See Also

IRowset::GetData, IRowsetLocate::GetRowsAt, IRowsetLocate::GetRowsByBookmark