MDAC 2.5 SDK - OLE DB Programmer's Reference
Chapter 9: Row and Stream Objects
A consumer obtains a row object in one of the following ways:
To create a row object directly with IOpenRowset, the consumer calls IOpenRowset::OpenRowset on the current session object. However, by default, IOpenRowset::OpenRowset returns a rowset object, so to obtain a row object instead of a rowset object, the consumer must do one of the following when calling IOpenRowset::OpenRowset:
To obtain a row object, the consumer calls IDBCreateCommand::CreateCommand on the session object to obtain a command object and then calls ICommand::Execute on the command object, requesting a row object instead of a rowset. If the command is one that returns a row, such as a singleton SQL SELECT statement, and if the provider supports creating row objects via commands, ICommand::Execute returns a row object. By default, ICommand::Execute returns a rowset object. To obtain a row object instead of a rowset object, the consumer must do one of the following when calling ICommand::Execute:
OLE DB does not require providers to know the number of rows to be returned for a given SELECT statement. If the consumer has requested a row object and if the command would otherwise return a rowset of two or more rows, the provider should return only the first row (as a row object), along with a return code of DB_S_NOTSINGLETON.
Note The "first row" is defined to be the first row of the rowset that would be returned if a rowset was requested and IRowset::GetNextRows was called with lRowsOffset set to zero. Also, it can be difficult or expensive for some providers to determine that the command would return a rowset with more than one row, so providers are not required to return DB_S_NOTSINGLETON.
The consumer can obtain a row object for a row in a rowset by calling IGetRow::GetRowFromHROW on the row handle (HROW) of the row. GetRowFromHROW creates a new row object each time it is called.
Conversely, the method IRow::GetSourceRowset allows the consumer to obtain the source rowset for a row object. Row objects are permitted, but not required, to keep references on source rowsets.
Using the two methods discussed above, the consumer can navigate between a rowset and a row object.
If a row object has a source rowset and changes to this rowset are deferred, changes to all columns of the row object are also deferred. Thus, IRow::GetColumns returns the current value of all row columns, and the original values of row columns that are not part of the source rowset are unavailable. Updates to row column values, via IRowChange::SetColumns or IRowSchemaChange::AddColumns, are not propagated to the underlying data store until IRowsetUpdate::Update is called on the source rowset.
Note IRowsetUpdate::Undo can also undo changes made to row-specific columns.
If a row object is created from a source rowset that implements IRowsetRefresh to synchronize the rowset with its data store, the row-specific column values of the row object are refreshed along with those defined by the source rowset.
Note If a row is derived from a source rowset, changes made to a column by using the row object are visible when the column is retrieved using the source rowset. The reverse is also true; that is, changes made to a column value by using the rowset are visible when that column is accessed using the row object. If multiple row objects are created from the same HROW via calls to GetRowFromHROW, visibility to the other row objects of changes made to a specific row object is governed by properties of the source rowset such as DBPROP_OWNUPDATEDELETE.
IGetRow::GetURLFromHROW can be used to obtain the URL of a row in a rowset. The consumer can then use this URL in a call to IBindResource::Bind (or IScopedOperations::Bind, if the URL represents a row in the scope of the row object on which the IScopedOperations interface was obtained) to create a new row object for this row.
In addition, DBROWCOL_ROWURL is provided as a shortcut column ID (DBID) on a row object to identify the column, if any, that contains the URL of that row. For more information about the row URL column and DBROWCOL_ROWURL, see "Special Row Column DBIDs" later in this chapter.