IRowsetFind::FindNextRow

Begins at the specified bookmark and finds the next row matching the specified value.

Syntax

HRESULT FindNextRow (
   HCHAPTER            hChapter,
   HACCESSOR           hAccessor,
   void               *pFindValue,
   DBCOMPAREOP         CompareOp,
   DBBKMARK            cbBookmark,
   const BYTE         *pBookmark,
   DBROWOFFSET         lRowsOffset,
   DBROWCOUNT          cRows,
   DBCOUNTITEM        *pcRowsObtained,
   HROW              **prghRows);

Parameters

  • hChapter
    [in] The chapter handle designating the rows to find. For nonchaptered rowsets, the caller must set hChapter to DB_NULL_HCHAPTER. For chaptered rowsets, DB_NULL_HCHAPTER designates the entire rowset.

  • hAccessor
    [in] Accessor describing the value to be matched. This accessor must describe only a single column. If it describes more than one column, IRowsetFind::FindNextRow returns DB_E_BADBINDINFO.

    Valid coercions for IRowsetFind::FindNextRow are the same as those for IRowsetChange::SetData.

  • pFindValue
    [in] Pointer to the value to be matched. If this indicates a null value (a variant of type VT_NULL or a status value of DBSTATUS_ISNULL), it is compared equal to null values and not equal to non-null values, within the rowset. It is provider-specific whether null values are compared greater than or less than non-null values.

  • CompareOp
    [in] Operation to use in comparing the row values. The consumer should check DBPROP_FINDCOMPAREOPS to determine which comparison operators the provider supports.

    Only DBCOMPAREOPS_EQ, DBCOMPAREOPS_NE, and DBCOMPAREOPS_IGNORE are valid for the following values of CompareOp:

    • DBTYPE_BOOL

    • DBTYPE_ERROR

    • DBTYPE_GUID

    • DBTYPE_IDISPATCH

    • DBTYPE_IUNKNOWN

    • DBTYPE_BYTES

    The values in DBCOMPAREOPSENUM have the meanings described in the following table.

    Value

    Description

    DBCOMPAREOPS_LT

    Match the first value that is less than the search value.

    DBCOMPAREOPS_LE

    Match the first value that is less than or equal to the search value.

    DBCOMPAREOPS_EQ

    Match the first value that is equal to the search value.

    DBCOMPAREOPS_GE

    Match the first value that is greater than or equal to the search value.

    DBCOMPAREOPS_GT

    Match the first value that is greater than the search value.

    DBCOMPAREOPS_BEGINSWITH

    Match the first value that has the search value as its first characters. This is valid only for values bound as string data types.

    DBCOMPAREOPS_NOTBEGINSWITH

    Match the first value that does not have the search value as its first characters. This is valid only for values bound as string data types.

    DBCOMPAREOPS_CONTAINS

    Match the first value that contains the search value. This is valid only for values bound as string data types.

    DBCOMPAREOPS_NOTCONTAINS

    Match the first value that does not contain the search value. This is valid only for values bound as string data types.

    DBCOMPAREOPS_NE

    Match the first value that is not equal to the search value. If the search value is NULL, this matches the first non-NULL value. If the search value is non-NULL, this matches the first non-NULL value that is not equal to the search value.

    DBCOMPAREOPS_IGNORE

    Ignore the corresponding value.

    The provider ignores pFindValue and returns the next cRows rows starting from the row indicated by pBookmark, skipping the number of rows indicated by lRowsOffset.

    NoteNote
    DBCOMPAREOPS_IGNORE must be supported by all providers that implement IRowsetFind or IViewFilter.

    DBCOMPAREOPS_CASESENSITIVE and DBCOMPAREOPS_CASEINSENSITIVE

    Specify whether the search is case-sensitive or case-insensitive.

    You can join DBCOMPAREOPS_CASESENSITIVE or DBCOMPAREOPS_CASEINSENSITIVE with any of the other DBCOMPAREOPS values in a bitwise OR operation. If neither is used, the search is handled according to the provider's implementation. Both DBCOMPAREOPS_CASESENSITIVE and DBCOMPAREOPS_CASEINSENSITIVE are ignored when searching for nonstring values.

  • cbBookmark
    [in] Length in bytes of the bookmark, or zero to start from the next fetch location. (See the description of pBookmark.)

  • pBookmark
    [in] Pointer to a bookmark that, in combination with lRowsOffset, 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.

    To request that the find occur starting with the next fetch location, the consumer can specify a cbBookmark value of zero and set pBookmark to null. The next fetch location is the same as the next fetch position used by IRowset::GetNextRows.

    If cbBookmark equals zero, the provider ignores pBookmark.

    If the rowset does not support IRowsetLocate, only the special bookmarks DBBMK_FIRST and DBBMK_LAST, and the null value, may be used.

    If the rowset does not support scrolling backward, only the null bookmark value may be used.

    If the rowset is chaptered, the identified row must fall within the specified chapter.

  • lRowsOffset
    [in] The signed count of rows from the origin bookmark to the row at which to start searching for a match. The first row checked is determined by the bookmark and this offset. For example, if lRowsOffset is 0, the first row checked is the bookmarked row; if lRowsOffset is 1, the first row checked is the row after the bookmarked row; if lRowsOffset is -1, the first row checked is the row before the bookmarked row. This can be a negative number only if the value of the DBPROP_CANSCROLLBACKWARDS property is VARIANT_TRUE.

  • cRows
    [in] The number of rows to fetch from the rowset, starting with the first row found. A negative number indicates a backward fetch. The consumer can determine whether the provider supports fetching backward by checking the value of the DBPROP_CANFETCHBACKWARDS property returned by IRowsetInfo::GetProperties.

    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. In this case, if cbBookmark is zero, the next fetch position is moved to the same position as if calling IRowsetFind::FindNextRow with cRows equal to 1 and releasing the retrieved row. In general, consumers should avoid calling IRowsetFind::FindNextRow with cRows equal to zero.

    Note

    Calling IRowsetFind::FindNextRow with a cbBookmark value of zero searches for a column value relative to the current IRowset::GetNextRows position. Following the call to IRowsetFind::FindNextRow, the fetch for IRowset::GetNextRows is also moved. Calling IRowsetFind::FindNextRow with a cbBookmark value of zero and a cRows value of zero is defined as setting the next fetch position to the same location as by calling IRowsetFind::FindNextRow with a cbBookmark value of zero and a cRows value of one.

    In general, it is not useful to call IRowsetFind::FindNextRow with a cRows value of zero. Due to ambiguity in the previous versions of the OLE DB Programmer's Reference, some providers may not implement the next fetch position as defined, and consumers should not rely on the next fetch position following a call to IRowsetFind::FindNextRow with a cbBookmark value of zero and a cRows value of zero.

  • 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 0 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
    IRowsetFind::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. Therefore, 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 required 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. IRowsetFind::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. Therefore, whenever a consumer receives the return code for another warning condition, it should check to see whether this condition occurred.

  • E_FAIL
    A provider-specific error occurred.

  • E_INVALIDARG
    pcRowsObtained or prghRows was a null pointer.

    cbBookmark was not 0, and pBookmark was a null pointer.

  • E_OUTOFMEMORY
    The provider was unable to allocate sufficient memory in which to instantiate 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 and DBPROP_BOOKMARKSKIPPED was VARIANT_FALSE.

    *pBookmark was not a null value, and the rowset does not support scrolling backward.

    *pBookmark was not DBBMK_FIRST, DBBMK_LAST, or a null value, and the rowset does not support IRowsetLocate.

    The rowset was chaptered, and *pBookmark did not apply to the specified chapter.

    Note

    Consumers should attempt to use only bookmarks that they have received from the provider. The provider is guaranteed only to handle bookmarks it gives out in a predictable manner. Attempting to use a random value as a bookmark is undefined; the provider may return DB_E_BADBOOKMARK, may return an unexpected row, or may terminate abnormally.

  • DB_E_BADCHAPTER
    The rowset was chaptered, and hChapter was invalid.

    The rowset was single-chaptered, and the specified chapter was not the currently open chapter. The consumer must use the currently open chapter or release the currently 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.

    Both DBCOMPAREOPS_CASESENSITIVE and DBCOMPAREOPS_CASEINSENSITIVE were used in the same operation.

    The specified CompareOp could not be supported on the column, or the column was not searchable.

  • DB_E_BADSTARTPOSITION
    lRowsOffset indicated a position either more than one row before the first row of the rowset or more than one row after the last row, and the provider was a 1.x provider.

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

    lRowsOffset was negative, and the rowset cannot scroll backward.

  • DB_E_NOTREENTRANT
    The provider called a method from IRowsetNotify in the consumer that had not yet returned, and the provider does not support reentrancy in this method.

  • DB_E_ROWSNOTRELEASED
    The provider requires release of prior HROWs before new ones can be obtained. (See IDBProperties::GetPropertyInfo, DBPROP_CANHOLDROWS.)

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

Comments

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.

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

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

For a newly created rowset, if pBookmark is null, the search begins starting with the row computed according to the next fetch position as described in IRowset::GetNextRows for newly created rowsets.

It is not required that the rowset be ordered on the column searched. IRowsetFind::FindNextRow always finds the next row according to the criteria, regardless of the sort order.

IRowsetFind::FindNextRow increments the reference count of each row for which it returns a handle by 1. 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 ? IRowsetFind::FindNextRow 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.

If an error occurs when calling IRowsetFind::FindNextRow, the next fetch position is left unchanged.

If IRowsetFind::FindNextRow performs deferred accessor validation and that validation takes place before any data is transferred, it can also return any of the following return codes for the applicable reasons listed in the corresponding DBBINDSTATUS values in IAccessor::CreateAccessor: E_NOINTERFACE, DB_E_BADBINDINFO, DB_E_BADORDINAL, DB_E_BADSTORAGEFLAGS, and DB_E_UNSUPPORTEDCONVERSION.

For information about what IRowsetFind::FindNextRow does when it fetches a row that it already has in its internal buffers, see Uniqueness of Rows in the Rowset. For information about whether IRowsetFind::FindNextRow can detect changes made to rows in the rowset, see Visibility of Changes. For information about how IRowsetFind::FindNextRow interprets data from *pFindValue, see Setting Data.

See Also

Reference

IRowset::GetData

IRowsetIndex::Seek

IRowsetLocate::GetRowsAt

IRowsetLocate::GetRowsByBookmark