IMDDataset::GetCellData

Returns the cell value, formatted value, cell ordinal number, and other requested properties of a range of cells.

HRESULT GetCellData(
   HACCESSOR         hAccessor,
   ULONG               ulStartCell,
   ULONG               ulEndCell,
   VOID*               pData);

Parameters

hAccessor[in]

The handle of the accessor to use. If hAccessor is the handle of a null accessor, then IMDDataset::GetCellData doesn’t get any data or property values.

ulStartCell[in]

The cell ordinal of the first cell in the range.

ulEndCell[in]

The cell ordinal of the last cell in the range.

pData[out]

A pointer to the buffer in which to return the data. The consumer allocates memory for this buffer.

Return Code

S_OK
The method succeeded. The status of all columns (cell properties) for all rows (cells) bound by the accessor is set to one of DBSTATUS_S_OK, DBSTATUS_S_ISNULL, or DBSTATUS_S_TRUNCATED.

DB_S_ERRORSOCCURRED
An error occurred while returning data for one or more columns (cell properties) in one or more rows (cells), but data was successfully returned for at least one property of one cell. To determine the cells or properties 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 “Possible Return and Status Values” in the comments section.

E_FAIL
A provider-specific error occurred.

E_INVALIDARG
pData was a null pointer and the accessor wasn’t a null accessor.

ulStartCell or ulEndCell is invalid.

DB_E_BADACCESSORHANDLE
hAccessor was invalid. Providers aren’t 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.

DB_E_ERRORSOCCURRED
Errors occurred while returning data for all properties of all cells. 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 “Possible Return and Status Values” in the comments section.

MD_E_INVALIDCELLRANGE
cbRowSize of the IAccessor::CreateAccessor call that created hAccessor was 0, and ulStartCell was not equal to ulEndCell.

ulStartCell was greater than ulEndCell and ulEndCell wasn’t zero.

ulStartCell, ulEndCell, or both specified a cell ordinal that wasn’t in the dataset.

If this method performs deferred accessor validation and that validation takes place before any data is transferred, it can also return for the reasons listed in the corresponding DBBINDSTATUS values in IAccessor::CreateAccessor any of the following return codes:

Comments

This method allows for the retrieval of a dataset slice. The consumer identifies the desired slice by specifying the ulStartCell and ulEndCell parameters; ulStartCell is the upper left corner of the slice and ulEndCell is the lower right corner of the slice. Because these parameters are used to identify the slice, not all cells between ulStartCell and ulEndCell are necessarily fetched. This is illustrated in the following diagram of a two-axis dataset. The heavily outlined cells are the slice of the dataset identified by ulStartCell and ulEndCell. They are fetched. The shaded cells have ordinal values less that ulEndCell and greater than ulStartCell, but are not fetched.

Determining Cell Ordinals

To facilitate navigation among cells, OLE DB for OLAP uses an ordinal value system to uniquely identify cells within a dataset. The ordinal value is computed from the tuple ordinals of the tuples forming the cell coordinates. The tuple ordinal is the zero-based distance of the tuple from the origin of that axis.

Conceptually, cells are numbered in a dataset as if the dataset were a p-dimensional array, where p is the number of axes. Cells are addressed in row-major order. Below is the formula for calculating the ordinal number of a cell:

Available Data

Each cell is treated as a row in a rowset, and cell properties are treated as columns. The actual properties available depend on the MDX expression that generated the dataset. For a detailed discussion of cell properties, see “Retrieving Cell Properties” in Chapter 2. IColumnsInfo can also be used to find out the number of columns or properties available, and name, data type, and so on.

Special Cases

If the consumer specifies zero for ulStartCell and a nonzero value for ulEndCell, the provider fetches the cells in the slice identified by the first cell in the dataset and the specified ending cell. If the consumer specifies a nonzero value for ulStartCell and zero for ulEndCell, the provider fetches the cells in the slice identified by the specified start cell and the last cell in the dataset. Except for this case, it is an error to have ulStartCell greater than ulEndCell.

If the consumer specifies a ulStartCell or ulEndCell value that falls outside the dataset, the method fails.

Possible Return and Status Values

As the provider returns cell data, it sets the status field of each bound property value buffer. Using this value, the consumer can determine which property values were successfully fetched.

Note   Consumers are strongly encouraged to bind to status values. If the status is other than DBSTATUS_S_OK, the provider is not obligated to touch the value part of the consumer’s buffer.

The method produces return values as follows:

The following table lists all possible status values:



Status value
Success, warning, or error
Data
returned


Description
DBSTATUS_S_OK Success Y A non-NULL value was returned by the provider.
DBSTATUS_S_
ISNULL
Success Y A NULL value was returned by the provider.
MDSTATUS_S_
CELLEMPTY
Success Y The cell was empty. This occurs when there is no data in the cube at the coordinates of the cell. Using the NON EMPTY clause of the MDX statement guarantees that there are no empty cells.
DBSTATUS_S_
TRUNCATED
Warning Y Variable length data or nonsignificant digits of numeric data were truncated.
DBSTATUS_E_
BADACCESSOR
Error N Accessor validation was deferred and was performed while the method returned data. The binding was invalid for this column or parameter.
DBSTATUS_E_
CANTCONVERTVALUE
Error N The data value couldn’t be converted for reasons other than sign mismatch or data overflow. For example, the data in the data source was corrupted but the row was still retrievable.
DBSTATUS_E_CANTCREATE Error N One of the following conditions:
  • The provider couldn’t allocate memory in which to return data.

  • The type indicator for the column was DBTYPE_IUNKNOWN and a storage object was already open on the column.

  • The type indicator for the column was DBTYPE_IUNKNOWN, the provider supports only one open storage object at a time (DBPROP_MULTIPLESTORAGEOBJECTS was VARIANT_FALSE), and a storage object was already open on the rowset.
DBSTATUS_E_
DATAOVERFLOW
Error N Conversion failed because the data value overflowed the type specified for the value part in the consumer’s buffer.
DBSTATUS_E_
SIGNMISMATCH
Error N Conversion failed because the data value was signed and the type specified for the value part in the consumer’s buffer was unsigned.
DBSTATUS_E_UNAVAILABLE Error N Value couldn’t be determined by the provider. For example, the row was just created, the default for the column wasn’t available, and the consumer hadn’t yet set a new value.

Errors During Cell Fetch

When fetching a range of cells, there can be errors in fetching a given column or property of a given row or cell. Examples of such errors include truncation and arithmetic overflow. This does not necessarily invalidate all the data fetched. Errors are localized to individual columns and are indicated in the STATUS part of the consumer’s buffer for each column. This is a 2-byte field containing manifest constants denoting different error and status indicators. The status indicators are listed and their meanings are defined in the OLE DB Programmer’s Reference.

Using cbRowSize of IAccessor::CreateAccessor

Because this method fetches properties for more than one cell, the provider should know how long each row is. A “row” in this context means the area allocated in the consumer’s buffer to hold all properties pertaining to one cell. This information should be given in the cbRowSize parameter of IAccessor::CreateAccessor. If the value of this parameter is zero, it means that the consumer wants to fetch only one row of data (one cell). In this case, it is an error to specify a ulStartCell different from the ulEndCell.

The consumer’s buffer for holding cell data must be laid out in such a way that each row is directly adjacent to the next row. Within a row, the columns must be laid out at the offsets specified by the DBBINDING structure. There must be enough space allocated to fetch the requested number of cells. Consumers are advised to pad cbRowSize appropriately for machine alignment (Intel®, 4-byte).