Getting Data (OLE DB)
To get data ? for example, by using IRowset::GetData for rowset data or ICommand::Execute for output parameter data ? the consumer must perform the following actions:
Create an accessor to bind the columns or output parameters.
Allocate a buffer to hold the data returned by the provider.
Call a method that gets data and passes the handle to the accessor and a pointer to the buffer.
For each column or output parameter specified in the accessor, the provider performs the actions in the following procedure. This procedure assumes that the consumer has bound the value, length, and status for each column or output parameter. If any of these are not bound, the procedure is the same except that the provider does not return the unbound part.
Note
If the accessor is a reference accessor, the provider does not follow this procedure but returns a pointer to the provider's memory that contains the data. For more information, see Reference Accessors.
Validate the accessor against the metadata if it has not already done so.
The provider can validate the entire accessor before returning any data or on a binding-by-binding basis while returning data. If validation fails in the former case, the provider produces the appropriate return code and does not return any data. If it fails in the latter case, the provider sets the status of the column or output parameter to DBSTATUS_E_BADACCESSOR and proceeds to the next column or output parameter.
Check whether the data is NULL.
If it is, either the provider sets the status to DBSTATUS_S_ISNULL and ignores the value and length or, in the case of variant data, the provider sets the status to DBSTATUS_S_OK and sets the value to VT_NULL. The provider then proceeds to the next column or output parameter. The address where the status value is placed is calculated from the buffer address passed to the method and the obStatus element of the binding. A variant whose type is VT_NULL is different from a column status of DBSTATUS_S_ISNULL. Providers supporting variants, as well as consumers binding to variants, must be prepared to handle either type of NULL. However, if DBSTATUS_S_ISNULL is specified in the status binding, the contents of the value binding, regardless of type, are undefined.
Convert the data to the type specified by the wType element of the binding.
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 Getting Data" in Status. For more information about converting data, see Data Type Conversion Rules in Appendix A: Data Types.
Set the length.
The address where the length value is placed is calculated from the buffer address passed to the method and the obLength element of the binding as follows:
Variable-length data types ? The length of the untruncated data in bytes, not counting the null-termination character for strings.
Fixed-length data types ? The size of the data type. If wType is DBTYPE_IUNKNOWN or DBTYPE_IDISPATCH, the length is sizeof(IUnknown*), not the size of the object to which the interface pointer points. If wType is DBTYPE_BSTR, the length is sizeof(BSTR), not the length of the string itself.
DBTYPE_BYREF ? Does not affect the length value. For example, if wType is DBTYPE_BYREF | DBTYPE_STR, the length is the length in bytes of the string, not the length of the pointer.
DBTYPE_VECTOR, DBTYPE_ARRAY ? If the type indicator is joined in a logical OR with DBTYPE_ARRAY or DBTYPE_VECTOR, the length is sizeof(SAFEARRAY*) and sizeof(DBVECTOR), respectively.
Set the data value to the converted data.
The address where the data value is stored is calculated from the buffer address passed to the method and the obValue element of the binding as follows:
Variable-length data types ? If the length in bytes of the converted, variable-length data is greater than cbMaxLen bytes, the provider truncates the data to cbMaxLen bytes before placing it in the consumer buffer and sets the status to DBSTATUS_S_TRUNCATED. Otherwise, the provider places the data in the consumer buffer without truncating it. For more information, see String Data.
Fixed-length data types ? The provider places the converted, fixed-length data in the consumer's buffer. The provider ignores cbMaxLen. It does not truncate the data before placing it in the consumer's buffer.
If the type indicator is DBTYPE_IUNKNOWN or DBTYPE_IDISPATCH, the data value is a pointer to an interface on the COM object, not the object itself. For more information, see BLOBs and COM Objects (OLE DB).
If the type indicator is DBTYPE_BSTR, the provider places the converted data in a BSTR and places the BSTR in the consumer's buffer. The provider ignores cbMaxLen. It does not truncate the data before placing it in the consumer's buffer. For information about how the BSTR is allocated and freed, see Responsibility for Freeing Memory.
DBTYPE_BYREF, DBTYPE_VECTOR, DBTYPE_ARRAY ? For DBTYPE_BYREF, the provider places the converted data in separately allocated memory and places a pointer to this memory in the consumer's buffer. For DBTYPE_VECTOR, the provider places the converted data in an array and places the count of array elements and a pointer to the array in a DBVECTOR structure in the consumer's buffer. For DBTYPE_ARRAY, the provider places the converted data in a SAFEARRAY structure and places a pointer to the SAFEARRAY in the consumer's buffer. In each case, the provider ignores cbMaxLen. That is, it does not truncate the data before placing it in the separate memory, array, or SAFEARRAY. For information about how the separate memory, array, or SAFEARRAY is allocated and freed, see Responsibility for Freeing Memory.
Set the status to DBSTATUS_S_OK if it hasn't already been set to another value.
If the provider encounters an error while returning a column or output parameter value, it sets the status value of that column or output parameter. The provider then continues to process the remaining columns or output parameters. After it has processed all columns or output parameters, if one or more errors have occurred, the provider produces one of the following return codes:
DB_S_ERRORSOCCURRED ? The method successfully returned data for at least one column or output parameter.
DB_E_ERRORSOCCURRED ? The method did not successfully return data for any columns or output parameters.
The consumer checks the status values to determine the columns or output parameters for which data was successfully returned. If the consumer did not bind a status value for a column or output parameter and a method returns DB_S_ERRORSOCCURRED or DB_E_ERRORSOCCURRED, the consumer must assume that all column or output parameter values were not successfully returned.
The provider frees any memory it allocated for return to the consumer but did not return to the consumer due to an error. If the method fails completely, the contents of the consumer's buffer are undefined.
This topic is a part of: