IRowset::ReleaseRows
Releases rows.
Syntax
HRESULT ReleaseRows (
DBCOUNTITEM cRows,
const HROW rghRows[],
DBROWOPTIONS rgRowOptions[],
DBREFCOUNT rgRefCounts[],
DBROWSTATUS rgRowStatus[]);
Parameters
cRows
[in] The number of rows to release. If cRows is zero, IRowset::ReleaseRows does not do anything.rghRows
[in] An array of handles of the rows to be released. The row handles need not form a logical cluster; they may have been obtained at separate times and need not be for contiguous underlying rows. Row handles are decremented by one reference count for each time they appear in the array.rgRowOptions
[in] An array of cRows elements containing bitmasks indicating additional options to be specified when releasing a row. This parameter is reserved for future use and should be set to a null pointer.typedef DWORD DBROWOPTIONS;
rgRefCounts
[out] An array with cRows elements in which to return the new reference count of each row. If rgRefCounts is a null pointer, no counts are returned. The consumer allocates, but is not required to initialize, memory for this array and passes the address of this memory to the provider. The provider returns the reference counts in the array.rgRowStatus
[out] An array with cRows elements in which to return values indicating the status of each row specified in rghRows. If no errors or warnings occur while releasing a row, the corresponding element of rgRowStatus is set to DBROWSTATUS_S_OK. If an error or warning occurs while releasing a row, the corresponding element is set as specified in DB_S_ERRORSOCCURRED. The consumer allocates memory for this array. If rgRowStatus is a null pointer, no row statuses are returned.
Return Code
S_OK
The method succeeded. All rows were successfully released. The following values can be returned in *prgRowStatus:The row was successfully released. The corresponding element of *prgRowStatus contains DBROWSTATUS_S_OK.
A row had a pending change. The row was released, and the corresponding element of rgRowStatus contains DBROWSTATUS_S_PENDINGCHANGES.
DB_S_ERRORSOCCURRED
An error occurred while releasing a row, but at least one row was successfully released. Successes and warnings can occur for the reasons listed under S_OK. The following errors can occur:A row handle was invalid. The row was not released, and the corresponding element of rgRowStatus contains DBROWSTATUS_E_INVALID.
The consumer encountered a recoverable, provider-specific error, such as an RPC failure when transmitting the change to a remote server. The corresponding element of rgRowStatus contains DBROWSTATUS_E_FAIL.
E_FAIL
A provider-specific error occurred.E_INVALIDARG
rghRows was a null pointer, and cRows was not equal to zero.E_UNEXPECTED
DBPROP_BLOCKINGSTORAGEOBJECTS is VARIANT_TRUE, and IRowset::ReleaseRows is called on a row with an open storage object. If the consumer, on cleanup, encounters an error while releasing the row, it should release the storage object first.DB_E_ERRORSOCCURRED
Errors occurred while releasing all of the rows. Errors can occur for the reasons listed under DB_S_ERRORSOCCURRED.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.
Comments
IRowset::ReleaseRows decreases the reference count on the specified rows. It must be called once for each time that a row was fetched. For example, if the row was fetched three times, IRowset::ReleaseRows must be called three times. Furthermore, if a row handle is duplicated in rghRows, the corresponding row will have its reference count decremented by one for each time it appears in the array.
If a provider doesn't support exact reference counts on rows, it should return a reference count of 1 while the row is active. Consumers should be aware of this behavior and should use the returned reference count for debugging purposes only; consumers should not rely on the returned reference count to indicate whether the row would survive another release. In this case, a provider may choose to return S_OK for any and all calls to IRowset::ReleaseRows until the rowset itself is released.
If a consumer calls IRowset::ReleaseRows on a row with pending changes, the row remains valid and ReleaseRows returns DBROWSTATUS_S_PENDINGCHANGES in rgRowStatus.
When the reference count for a row decreases to zero, the row is released under the following circumstances:
Subject to the rules of the current transaction, the rowset is free to discard any resources used by a row that has a reference count of zero. For example, these might include memory, locks, and original values. When the rowset actually discards these resources is provider-specific.
If the row has pending changes, the row still remains valid even though its reference count is zero. Consumers should not use the handle of a row that has a reference count of zero, even though the handle might still be valid. If IRowsetUpdate::Update is called to transmit pending changes for a row with a reference count of zero to the data store, it transmits the changes of the row and releases the row and its resources if the update succeeds. If IRowsetUpdate::Undo is called to undo the pending changes for a row with a reference count of zero, it releases the row and its resources.
Pending changes are not lost when releasing a reference count obtained from IRowsetLocate::GetRowsAt. A provider may take its own reference count on the row handle or store the row internally until pending changes are committed or dismissed (using IRowsetUpdate::Update or IRowsetUpdate::Undo).
After a row is released, methods called with the handle to that row return DB_E_BADROWHANDLE if the row has pending changes. After the pending changes are transmitted to the data store, methods might continue to return this error. However, the provider might have an implementation that recycles row handles and thereafter cannot detect the misuse. Because provider behavior varies, consumers should not use the handles of released rows.
If IRowset::ReleaseRows encounters an error while decrementing the reference count of a row or releasing the row, it sets the corresponding element in rgRowStatus to the appropriate DBROWSTATUS value and continues processing.
This method can be called while the rowset is in a zombie state to allow the consumer to clean up after a transaction has been committed or aborted.