Retrieves data from the rowset's copy of the row.
HRESULT GetData ( HROW hRow, HACCESSOR hAccessor, void *pData);
Parameters
Caution The consumer must ensure that hRow contains a valid row handle; the provider might not validate hRow before using it. The result of passing the handle of a deleted row is provider-specific, although the provider cannot terminate abnormally. For example, the provider might return DB_E_BADROWHANDLE, DB_E_DELETEDROW, or it might get data from a different row. The result of passing an invalid row handle in hRow is undefined.
Caution The consumer must ensure that hAccessor contains a valid accessor handle; the provider might not validate hAccessor before using it. The result of passing an invalid accessor handle in hAccessor is undefined.
Return Code
Comments
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 reasons listed in the corresponding DBBINDSTATUS values in IAccessor::CreateAccessor:
E_NOINTERFACE
DB_E_BADBINDINFO
DB_E_BADORDINAL
DB_E_BADSTORAGEFLAGS
DB_E_UNSUPPORTEDCONVERSION
This method makes no logical change to the state of the object.
A consumer calls IRowset::GetData to retrieve data from rows that have been fetched by prior calls to methods such as IRowset::GetNextRows. For a complete description of how IRowset::GetData retrieves data, see "Getting Data" in Chapter 6: Getting and Setting Data.
A consumer can call IRowset::GetData any number of times. In each call, it can pass a different accessor and the address of a different buffer. This means that the consumer can get as many copies of the data as it wants, and it can get data in different types if alternate conversions are available.
IRowset::GetData does not enforce any security restrictions. The provider must not create a rowset that includes columns for which the consumer does not have read privileges, so IRowset::GetData never encounters problems accessing the data for a column. The rowset can contain columns to which the consumer does not have write permission if DBPROP_COLUMNRESTRICT is VARIANT_TRUE. The methods that fetch rows must not return the handles of rows for which the consumer does not have read privileges, so IRowset::GetData never encounters problems accessing a row. Such rows might exist if the DBPROP_ROWRESTRICT property is VARIANT_TRUE.
If IRowset::GetData fails, the memory to which pData points is not freed but its contents are undefined. If before GetData failed the provider allocated any memory for return to the consumer, the provider frees this memory and does not return it to the consumer. The same is true if DB_E_ERRORSOCCURRED was returned but the consumer did not request status values in the binding.
IRowset::GetData must be reentrant during notifications. If the provider calls a method from IRowsetNotify in the consumer, the consumer must be able to call IRowset::GetData while processing the notification method.
The following example shows how a reference accessor is used.
#include <oledb.h> #include <stddef.h> IRowset * TheRowset; IAccessor * TheRowsetAccessor; HROW hRow; int main() { struct ExactlyTheSame { long l; double d; short i; }; HACCESSOR hRawAccess; static DBBINDING ExactBindings [3] = { { 1, // iOrdinal offsetof (ExactlyTheSame,l), // obValue 0, // No length binding 0, // No Status binding NULL, // No TypeInfo NULL, // No Object NULL, // No Extensions DBPART_VALUE, DBMEMOWNER_PROVIDEROWNED, // Ignored DBPARAMIO_NOTPARAM, sizeof (long), 0, DBTYPE_I4, 0, // No Precision 0 // No Scale }, { 2, // iOrdinal offsetof (ExactlyTheSame, d), // obValue 0, // No length binding 0, // No Status binding NULL, // No TypeInfo NULL, // No Object NULL, // No Extensions DBPART_VALUE, DBMEMOWNER_PROVIDEROWNED, // Ignored DBPARAMIO_NOTPARAM, sizeof (double), 0, DBTYPE_R8, 0, // No Precision 0 // No Scale }, { 3, // iOrdinal offsetof (ExactlyTheSame,i), // obValue 0, // No length binding 0, // No Status binding NULL, // No TypeInfo NULL, // No Object NULL, // No Extensions DBPART_VALUE, DBMEMOWNER_PROVIDEROWNED, // Ignored DBPARAMIO_NOTPARAM, sizeof (short), 0, DBTYPE_I2, 0, // No Precision 0 // No Scale } }; TheRowsetAccessor->CreateAccessor (DBACCESSOR_PASSBYREF, 3, ExactBindings, 0, &hRawAccess, NULL);
To read the column i of some row, the consumer should do the following:
short value; ExactlyTheSame * pRow; TheRowset->GetData(hRow, hRawAccess, &pRow); value = pRow->i;
The following example shows how provider-owned memory is used:
#include <oledb.h> #include <stddef.h> IRowset * TheRowset; IAccessor * TheRowsetAccessor; HROW hRow; int main() { struct IndirectlySimilar { long * pl; double * pd; short * pi; }; HACCESSOR hFastAccess; static DBBINDING IndirectBindings [3] = { { 1, // iOrdinal offsetof (IndirectlySimilar, pl), // obValue 0, // No length binding 0, // No Status binding NULL, // No TypeInfo NULL, // No Object NULL, // No Extensions DBPART_VALUE, DBMEMOWNER_PROVIDEROWNED, DBPARAMIO_NOTPARAM, sizeof (long*), 0, DBTYPE_BYREF|DBTYPE_I4, 0, // No Precision 0 // No Scale }, { 2, // iOrdinal offsetof (IndirectlySimilar, pd), // obValue 0, // No length binding 0, // No Status binding NULL, // No TypeInfo NULL, // No Object NULL, // No Extensions DBPART_VALUE, DBMEMOWNER_PROVIDEROWNED, DBPARAMIO_NOTPARAM, sizeof (double*), 0, DBTYPE_BYREF|DBTYPE_R8, 0, // No Precision 0 // No Scale }, { 3, // iOrdinal offsetof (IndirectlySimilar,pi), // obValue 0, // No length binding 0, // No Status binding NULL, // No TypeInfo NULL, // No Object NULL, // No Extensions DBPART_VALUE, DBMEMOWNER_PROVIDEROWNED, DBPARAMIO_NOTPARAM, sizeof(short*), 0, DBTYPE_BYREF|DBTYPE_I2, 0, // No Precision 0 // No Scale } }; TheRowsetAccessor->CreateAccessor (DBACCESSOR_ROWDATA, 3, IndirectBindings, 0, &hFastAccess, NULL );
To read the column i of some row, the consumer should do the following:
short value; IndirectlySimilar rowPs; TheRowset->GetData (hRow, hFastAccess, &rowPs); if (rowPs.pi) // Avoid null pointers value = *(rowPs.pi);
IRowset::GetNextRows | IRowsetChange::SetData