IRowsetChange::SetData

Sets data values in one or more columns in a row.

HRESULT SetData (
   HROW            hRow,
   HACCESSOR   hAccessor,
   void *            pData);

Parameters

hRow

[in]
The handle of the row in which to set data.

hAccessor

[in]
The handle of the accessor to use. If hAccessor is the handle of a null accessor (cBindings in IAccessor::CreateAccessor was zero), then SetData does not set any data values.

pData

[in]
A pointer to memory containing the new data values, at offsets that correspond to the bindings in the accessor.

Return Code

S_OK
The method succeeded. The status of all columns bound by the accessor is set to DBSTATUS_S_OK or DBSTATUS_S_ISNULL

DB_S_ERRORSOCCURRED
An error occurred while setting data for one or more columns, but data was successfully set for at least one column. To determine the columns for which data was returned, the consumer checks the status values. For a list of status values that can be returned by this method, see "Status Values Used When Setting Data" in "Status" in Chapter 6.

DB_S_MULTIPLECHANGES
The rowset was in immediate update mode and updating the row caused more than one row to be updated in the data source. For more information, see DBPROP_REPORTMULTIPLECHANGES in "Rowset Properties" in Appendix C.

This return code takes precedence over DB_S_ERRORSOCCURRED. That is, if the conditions described here and in those described in DB_S_ERRORSOCCURRED both occur, the provider returns this code. When the consumer receives this return code, it should also check for the conditions described in DB_S_ERRORSOCCURRED.

E_FAIL
A provider-specific error occurred.

E_INVALIDARG
pData was a null pointer and the accessor was not a null accessor.

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

DB_E_ABORTLIMITREACHED
The rowset was in immediate update mode and the row was not updated due to reaching a limit on the server, such as a query execution timing out.

DB_E_BADACCESSORHANDLE
hAccessor was invalid.

DB_E_BADACCESSORTYPE
The specified accessor was not a row accessor or was a reference accessor.

DB_E_BADROWHANDLE
hRow was invalid.

DB_E_CANCELED
The change was canceled during notification. No columns are changed.

DB_E_CANTCONVERTVALUE
The data value for one or more columns couldn't be converted for reasons other than sign mismatch or data overflow, and the provider was unable to determine which columns couldn't be converted. Providers that can detect which columns could not be converted return DB_S_ERRORSOCCURRED and set the status flag for the columns that couldn't be converted to DBSTATUS_E_CANTCONVERTVALUE.

DB_E_CONCURRENCYVIOLATION
The rowset was using optimistic concurrency and the value of a column has been changed since the containing row was last fetched or resynchronized. SetData returns this error only when the rowset is in immediate update mode.

DB_E_DATAOVERFLOW
Conversion failed because the data value for one or more columns overflowed the type used by the provider and the provider was unable to determine which columns caused the overflow. Providers that can detect which columns caused the overflow return DB_S_ERRORSOCCURRED and set the status flag for the columns in violation to DBSTATUS_E_DATAOVERFLOW.

DB_E_DELETEDROW
hRow referred to a row with a pending delete or for which a deletion had been transmitted to the data source.

DB_E_ERRORSOCCURRED
An error occurred while setting data for one or more columns and data was not successfully set for any columns. To determine the columns for which values were invalid, the consumer checks the status values. For a list of status values that can be returned by this method, see "Status Values Used When Setting Data" in "Status" in Chapter 6.

DB_E_INTEGRITYVIOLATION
The data violated the integrity constraints for one or more columns of the rowset and the provider was unable to determine which columns violated the integrity constraints. Providers that can detect which columns violated the integrity constraints return DB_S_ERRORSOCCURRED and set the status flag for the columns in violation to DBSTATUS_E_INTEGRITYVIOLATION.

DB_E_MAXPENDCHANGESEXCEEDED
The number of rows that have pending changes has exceeded the limit specified by the DBPROP_MAXPENDINGROWS property.

DB_E_NEWLYINSERTED
DBPROP_CHANGEINSERTEDROWS was VARIANT_FALSE and hRow referred to a row for which the insertion has been transmitted to the data source.

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_NOTSUPPORTED
The provider does not support this method.

DB_SEC_E_PERMISSIONDENIED
The consumer did not have sufficient permission to update the row. This error can be returned only if the value of the DBPROP_ROWRESTRICT property is VARIANT_TRUE. If the rowset is in delayed update mode, this error might not be returned until IRowsetUpdate::Update is called.

If this method 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
DB_E_UNSUPPORTEDCONVERSION

Comments

SetData sets data values in one or more columns in a row. For a complete description of how SetData sets data, see "Setting Data" in Chapter 6.

In delayed update mode, these changes are buffered locally in the rowset and are transmitted to the data source only when IRowsetUpdate::Update is called. In immediate update mode, the changes are immediately transmitted to the data source. For more information, see "Changing Data" in Chapter 5.

If a computed column depends on a column that is changed with SetData, the provider is not required to compute the new value of the computed column. If the provider computes the new value, it sends a notification to the consumer. If the provider does not compute the new value but lets the data source do so, then the computed value is not available until after the change is transmitted to the data source—that is, after SetData is called in immediate update mode or after IRowsetUpdate::Update if SetData is called in delayed update mode. To retrieve the computed value in this case, the consumer calls RefreshVisibleData or GetLastVisibleData in IRowsetRefresh. Bookmark columns are often computed, such as when the bookmark is the primary key or is a ROWID assigned by the data source.

If SetData changes a column that is used to order the rowset, the DBPROP_IMMOBILEROWS property describes whether the row is moved based on its new value. If this property is VARIANT_TRUE, the row is not moved. If this property is VARIANT_FALSE, the row is moved. If the rowset is not ordered, then the position of updated rows is not changed. Note that, if the rowset is built on a set of key columns (typically a rowset for which DBPROP_OTHERUPDATEDELETE is VARIANT_TRUE but DBPROP_OTHERINSERT is VARIANT_FALSE), changing the value of key column is generally equivalent to deleting the current row and inserting a new one. Thus, the row may appear to move or even disappear from the rowset (if DBPROP_OWNINSERT is VARIANT_FALSE), even though the DBPROP_IMMOBILEROWS property is VARIANT_TRUE.

When the consumer passes a pointer to a storage object to SetData, SetData replaces the data in the column with the data in the new storage object. If the consumer wants only to delete the data in the column, it sets the column status to DBSTATUS_S_OK and passes a null pointer instead of a pointer to a storage object. For more information, see "Getting and Setting BLOB Data with Storage Objects" in Chapter 7. If the rowset is in immediate update mode, storage object data is always transmitted immediately to the data source. If it is in delayed update mode, whether it is transmitted immediately or delayed depends on the DBPROP_DELAYSTORAGEOBJECTS property.

Although SetData can detect domain constraint and some table constraint schema violations, it is not required to do so. Such validation can be delayed until the changes are transmitted to the data source with Update or the transaction is committed with ITransaction::Commit. This delay is often necessary because of dependencies on values in other columns or tables.

SetData cannot be called for rows with pending or transmitted deletes.

The DBPROP_COLUMNRESTRICT and DBPROP_ROWRESTRICT properties affect how security is enforced and how security errors are returned. If DBPROP_COLUMNRESTRICT is VARIANT_TRUE, the consumer might not have write permission on some columns. If the consumer attempts to write to these columns, SetData returns a column status of DBSTATUS_E_PERMISSIONDENIED and a return code of DB_S_ERRORSOCCURRED. If the DBPROP_ROWRESTRICT property is VARIANT_TRUE, the consumer might not have permission to update some rows. If the consumer attempts to update one of
these rows, SetData returns a code of DB_SEC_E_PERMISSIONDENIED and no data is set.

If any consumer of the rowset is using notifications, the provider sends notifications. These notifications can be vetoed, in which case the provider sends the DBEVENTPHASE_FAILEDTODO phase of the notification. When the consumer then calls Update, if the update is in delayed mode, the provider does not send additional DBREASON_COLUMN_SET notifications for the rows. However, if Update computes the value of computed columns, it sends DBREASON_COLUMN_RECALCULATED notifications. In this case, the provider must either be prepared to undo all pending changes for the row, and return DBREASON_ROW_UNDOCHANGE, or set the fCantDeny flag to TRUE.

The following sequence of notifications occurs for a rowset operating in delayed update mode:

  1. If the row is being changed for the first time since it was created, or changes were transmitted, the provider sends the DBEVENTPHASE_OKTODO and DBEVENTPHASE_ABOUTTODO phases of the DBREASON_ROW_FIRSTCHANGE notification.

  2. The provider sends the DBEVENTPHASE_OKTODO, DBEVENTPHASE_ABOUTTODO, and DBEVENTPHASE_SYNCHAFTER phases of the DBREASON_COLUMN_SET notification, in that order, provided none of the listeners veto any of the phases. The notification covers all the columns defined by the accessor used in the call to SetData.

  3. The provider sends the DBEVENTPHASE_SYNCHAFTER phase of the DBREASON_ROW_FIRSTCHANGE notification, assuming the provider sent the earlier phases of this notification.

  4. The provider sends the DBEVENTPHASE_DIDEVENT phase of the DBREASON_COLUMN_SET notification.

  5. The provider sends the DBEVENTPHASE_DIDEVENT phase of the ROW_FIRSTCHANGE notification.

See Also

IRowset::GetData, IRowsetChange::InsertRow, IRowsetUpdate::Undo, IRowsetUpdate::Update