IRowset::GetData
Retrieves data from the rowset's copy of the row.
Syntax
HRESULT GetData (
HROW hRow,
HACCESSOR hAccessor,
void *pData);
Parameters
hRow
[in] The handle of the row from which to get the data.Warning
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.
hAccessor
[in] The handle of the accessor to use. If hAccessor is the handle of a null accessor (cBindings in IAccessor::CreateAccessor was zero), IRowset::GetData does not get any data values.Warning
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.
pData
[out] A pointer to a buffer in which to return the data. The consumer allocates memory for this buffer. This pointer must be a valid pointer to a contiguous block of consumer-owned memory into which the data will be written.
Return Code
S_OK
The method succeeded. The status of all columns bound by the accessor is set to DBSTATUS_S_OK, DBSTATUS_S_ISNULL, or DBSTATUS_S_TRUNCATED.DB_S_ERRORSOCCURRED
An error occurred while returning data for one or more columns, but data was successfully returned 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 Getting Data" in Status.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_BADACCESSORHANDLE
hAccessor was invalid. Providers are not required to check for this condition, because doing so might slow the method significantly.DB_E_BADACCESSORTYPE
The specified accessor was not a row accessor. Some providers may return DB_E_BADACCESSORHANDLE instead of this error code when command accessors are passed to the rowset.DB_E_BADROWHANDLE
hRow was invalid. Providers are not required to check for this condition, because doing so might slow the method significantly.DB_E_DELETEDROW
hRow referred to a pending delete row or a row for which a deletion had been transmitted to the data store. Providers are not required to check for this condition, because doing so might slow the method significantly.DB_E_ERRORSOCCURRED
Errors occurred while returning data for all columns. To determine what errors occurred, the consumer checks the status values. For a list of status values that can be returned by this method, see "Status Values Used When Getting Data" in Status.
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.
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);
// ...
return 0;
}
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 );
// ...
return 0;
}
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);