Handles for rows are used with accessors or other functions to manipulate the contents of the rows. Row handles are of type HROW, defined as follows:
typedef ULONG HROW;
# define DB_NULL_HROW 0x00 // Always invalid
The consumer can use row handles to manage the activity of individual rows or sets of rows. Any vector of row handles is allowed, and the consumer can rearrange them into different sets as long as the consumer keeps track of which rows are actively held and which have been released. Rowsets may have a row capacity (a limit on the number of rows that they can track), which is implied by the rowset specification.
When a consumer fetches a row, the data for the row appears to be cached in the provider and left there until the row is released. The consumer reaches the columns of the row through the functions IRowset::GetData and IRowsetChange::SetData, which use accessors to define how the data is to be transferred. For more information, see "Accessors" in Chapter 6.
Having a local copy of the row allows multiple consumers to get data from the row without making additional trips to the data source—which might reside on a separate server—and to coordinate changes to the row without transmitting them to the data source until all consumers are ready. Whether the row actually exists in the rowset is provider specific; for example, the row could be a representation of some object running on the provider or it could be a handle to a row in a lower-level service component.
However, caching rows in the provider means that it’s costly to keep materialized row handles—those defined by creating an instance. Even if a particular provider does not enforce a preset limit on the number of active row handles, it is likely that keeping these row handles even in the order of the hundreds will deteriorate provider performance. Thus, although some providers might be expected to handle rowsets with millions of rows, no provider is expected to materialize many rows simultaneously. Consumers are encouraged to release row handles whenever possible and keep bookmarks to these rows if it is necessary to refetch them. Consumers can keep a small number of frequently accessed row handles in materialized form.