Setting Data
To set data, such as with IRowsetChange::SetData for rowset data, or ICommand::Execute for input parameter data, the consumer performs the following actions:
-
Creates an accessor to bind the columns or input parameters.
-
Allocates a buffer to hold the data to pass to the provider.
-
Places data in this buffer. For more information, see the next procedure.
-
Calls a method that sets data and passes the handle to the accessor and a pointer to the buffer.
For each column, except as noted later, or input parameter specified in the accessor, the consumer performs the actions in the following procedure. When passing key values to an index rowset, the consumer performs this procedure only for the number of key columns specified in the cKeyValues argument in IRowsetIndex::Seek, or the cStartKeyValues or cEndKeyValues arguments in IRowsetIndex::SetRange.
Note This procedure assumes that the consumer has bound the value, length, and status for each column or input parameter. If any of these are not bound, the procedure is the same except that the consumer does not set the unbound part.
-
If the data is NULL, sets the status to DBSTATUS_S_ISNULL and proceeds to the next column or input parameter. If the provider is to use the default as the input value for an input or input/output parameter in a procedure, sets the status to DBSTATUS_S_DEFAULT and proceeds to the next column or input parameter. If the provider is to ignore this column in performing the insert or update, sets the status to DBSTATUS_S_IGNORE. Otherwise, sets the status to DBSTATUS_S_OK. The address at which the status value is placed is calculated from the buffer address passed to the method and the obStatus element of the binding.
-
If wType is DBTYPE_STR, DBTYPE_WSTR, and DBTYPE_BYTES, or any of these values combined with DBTYPE_BYREF, sets the length to the length of the data in bytes, not counting the null-termination character for strings. For all other data types, the provider ignores the length, so the consumer does not need to set it.
-
Sets the data value.
The address at which the data value is placed is calculated from the buffer address passed to the method and the obValue element of the binding. If wType is DBTYPE_BSTR or is combined with DBTYPE_BYREF, DBTYPE_VECTOR, or DBTYPE_ARRAY, the consumer places the data in separately allocated memory and places a pointer to the data in its buffer. For information about how this memory is allocated and freed, see "Memory Management" earlier in this chapter.
For each column, except as noted later, or input parameter specified in the accessor, the provider performs the actions in the following procedure. When passing key values to an index rowset, the provider performs this procedure only for the number of key columns specified in the cKeyValues argument in Seek, or the cStartKeyValues or cEndKeyValues arguments in SetRange. This procedure assumes that the consumer has bound the value, length, and status for each column or input parameter. If any of these are not bound, the procedure is the same except that the provider does not attempt to retrieve the unbound part from the consumer's buffer; for more information, see "Data Parts" earlier in this chapter.
-
Validates the accessor against the metadata if it has not already done so.
The provider can validate the entire accessor before setting any data or on a binding-by-binding basis while setting data. If validation fails in the former case, the provider produces the appropriate return code and does not set any data. If it fails in the latter case, the provider sets the status to DBSTATUS_E_BADACCESSOR and proceeds to the next column or output parameter.
-
Retrieves the status value from the consumer’s buffer.
If the status is DBSTATUS_S_ISNULL, the provider uses a null value and proceeds to the next column or input parameter. If the status is DBSTATUS_S_DEFAULT, the provider uses the default value and proceeds to the next column or input parameter. If the status is DBSTATUS_S_IGNORE, the provider skips the column and proceeds to the next column to be inserted or updated. If the status is DBSTATUS_S_OK, the provider proceeds to the next step. If the status is any other value, the provider sets the status to DBSTATUS_E_BADSTATUS and proceeds to the next column or input parameter. The address from which the status value is retrieved is calculated from the buffer address passed to the method and the obStatus element of the binding.
-
If wType is DBTYPE_STR, DBTYPE_WSTR, DBTYPE_BYTES, or one of these indicators combined with DBTYPE_BYREF, the provider retrieves the length from the consumer's buffer.
For all other data types, the provider ignores the length. The address from which the length value is retrieved is calculated from the buffer address passed to the method and the obLength element of the binding.
-
Retrieves the data value from the consumer's buffer. The address from which the data value is retrieved is calculated from the buffer address passed to the method and the obValue element of the binding.
-
Variable-length data types—The provider retrieves the number of bytes of variable-length data as specified by the length, up to cbMaxLen bytes. It is generally a consumer programming error if the length is greater than cbMaxLen. If no length is bound, the provider retrieves strings up to the first null-termination character; this is an error for DBTYPE_BYTES.
-
Fixed-length data types—The provider retrieves the number of bytes of fixed-length data from the consumer's buffer based on the size of the data type; it ignores cbMaxLen.
If the type indicator is DBTYPE_IUNKNOWN or DBTYPE_IDISPATCH, the provider retrieves a pointer to an interface on the object from the consumer's buffer. For information about how the provider retrieves the object itself, see Chapter 7, "BLOBs and OLE Objects."
If the type indicator is DBTYPE_BSTR, the provider retrieves the pointer to the BSTR from the consumer's buffer and the BSTR from the memory to which this pointer points. The provider ignores cbMaxLen; that is, it does not truncate the BSTR to cbMaxLen bytes.
-
DBTYPE_BYREF—The provider retrieves a pointer to the data from the consumer's buffer and the data from the memory to which this pointer points. The provider retrieves the data from this memory as if it were retrieving it directly from the consumer's buffer, except that it always ignores cbMaxLen, even when DBTYPE_BYREF is combined with DBTYPE_STR, DBTYPE_WSTR, or DBTYPE_BYTES.
-
DBTYPE_VECTOR—The provider retrieves a pointer to an array of data and a count of the number of elements in the array from a DBVECTOR structure in the consumer's buffer. It retrieves the data itself from the array to which this pointer points. The provider retrieves the data from this memory as if it were retrieving it directly from the consumer's buffer.
-
DBTYPE_ARRAY—The provider retrieves a pointer to a SAFEARRAY from the consumer's buffer. It retrieves the data from the SAFEARRAY to which this pointer points.
-
Converts the data from the type that is stored in the consumer's buffer, as specified by the wType element of the binding, to the type of the column or input parameter.
If an error occurs while converting the data, the provider sets the status accordingly and proceeds to the next column or output parameter. For a list of status values that describe conversion errors, see "Status Values Used When Setting Data" in "Status," earlier in this chapter. For more information about converting data, see "Data Type Conversion Rules" in Appendix A.
If the provider encounters an error while retrieving a column or input parameter value, it sets the status value of that column or input parameter. Depending on the provider, it does one of the following:
-
Stops processing and backs out any changes already made.
-
Stops processing and leaves any changes already made.
-
Continues processing some or all of the remaining columns or input parameters.
If the provider stops processing, it must set the status value of any column or input parameter that was not in error and was not successfully set to DBSTATUS_E_UNAVAILABLE. This way, the consumer can determine which column or input parameter values were valid, which were invalid, and which were not validated.
When setting column data, except when seeking a key value or setting the index range, the provider then produces one of the following return codes:
-
DB_S_ERRORSOCCURRED—The method successfully set data for at least one column.
-
DB_E_ERRORSOCCURRED—The method did not successfully set data for any columns.
When setting input parameter data, seeking a key value, or setting the index range, the provider then returns DB_E_ERRORSOCCURRED.
The consumer checks the status values to determine the columns or input parameters for which data was successfully set. If the consumer did not bind a status value for a column or input parameter and a method returns DB_S_ERRORSOCCURRED or DB_E_ERRORSOCCURRED, it must be assumed that the column or input parameter value was not successfully set.