Creating a Dataset and Getting Cell Data

OLE DB Programmer's Reference

MDPDataset is used to get the cell data for an MDX query specified by pwszQuery, compute the cell data coordinates, and call IMDDataset::GetCellData for each cell in the dataset.

// HRESULT MDPDataset(ICommandText *pICommandText, pwszQuery) {    HRESULT hr;    struct COLUMNDATA    {       SDWORD dwLength;     // length of data (not space allocated)       DBSTATUS dwStatus;   // status of column       VARIANT var;         // variant value    };    // Execute the MDX query.    IMDDataset* pIMDDataset = NULL;    hr = pICommandText->SetCommandText(DBGUID_MDX, pwszQuery);    hr = pICommandText->Execute(NULL, IID_IMDDataset, NULL, NULL,                                (IUnknown **)&pIMDDataset ));    // Fetch the axis info to compute the coordinates.    ULONG cAxis;    MDAXISINFO* rgAxisInfo = NULL;    hr = pIMDDataset->GetAxisInfo( &cAxis, &rgAxisInfo );    // Calculate the coordinate "offset factors". These are used to    // translate from a point in cell space to a set of axis coordinates.    // Example, consider a dataset with three axes and the following    // number of coordinates for each axis:    //   {x,y,z} = {3,4,5}    //      rgAxisOffset[2] = 3*4    //      rgAxisOffset[1] = 3    //      rgAxisOffset[0] = 1    // Thus, where p represents the cell's ordinal value:    //      z = p % 12    //      y = (p - z*12) % 3    //      x = (p - z*12 - y*3)    // And,    //      p = x + 3*y + 12*z    ULONG cAxisTuple;    ULONG iOffset = 1;    ULONG ulMaxCoord = 0;    ULONG rgAxisOffset[MAX_DIMS];   // array of offset multipliers    // For all axes, excluding slicer axis...    for (ULONG iAxis=0; iAxis < cAxis-1; iAxis++)    {       rgAxisOffset[iAxis] = iOffset;       cAxisTuple = rgAxisInfo[iAxis].cCoordinates;       iOffset *= cAxisTuple;    }    ulMaxCoord = iOffset;    ULONG cSliceCoord = rgAxisOffset[cAxis-1]    // Bind to the column values for each cell.    IColumnsInfo *pIColumnsInfo = NULL;    hr = pIMDDataset->QueryInterface(IID_IColumnsInfo,       (void**)&pIColumnsInfo);    ULONG cCol;    WCHAR* pStringsBuffer = NULL;    DBCOLUMNINFO* pInfo = NULL;    hr = pIColumnsInfo->GetColumnInfo(&cCol, &pInfo, &pStringsBuffer);    // Create bindings for each cell's columns, ordered as returned by    // GetColumnInfo. Bind everything as Variant.    dwOffset = 0;    ULONG iBind = 0;    ULONG cBind = 0;    for (ULONG iCol=0; iCol < cCol; iCol++)    {       rgBind[iBind].iOrdinal    = pInfo[iCol].iOrdinal;       rgBind[iBind].obValue     = dwOffset +          offsetof(COLUMNDATA,var);       rgBind[iBind].obLength    = dwOffset +          offsetof(COLUMNDATA,dwLength);       rgBind[iBind].obStatus    = dwOffset +          offsetof(COLUMNDATA,dwStatus);       rgBind[iBind].pTypeInfo   = NULL;       rgBind[iBind].pObject     = NULL;       rgBind[iBind].pBindExt    = NULL;       rgBind[iBind].cbMaxLen    = sizeof(VARIANT);       rgBind[iBind].dwFlags     = 0;       rgBind[iBind].eParamIO    = DBPARAMIO_NOTPARAM;       rgBind[iBind].dwPart      = DBPART_VALUE |                                   DBPART_LENGTH |                                   DBPART_STATUS;       rgBind[iBind].dwMemOwner  = DBMEMOWNER_CLIENTOWNED;       rgBind[iBind].wType       = DBTYPE_VARIANT;       rgBind[iBind].bPrecision  = 0;       rgBind[iBind].bScale      = 0;       dwOffset += rgBind[iBind].cbMaxLen + offsetof(COLUMNDATA,var);       iBind++;    }    cBind = iBind;    // Create the accessor.    IAccessor* pIAccessor;    hr = pIMDDataset->QueryInterface(IID_IAccessor, void**)&pIAccessor);    // Note that the value of dwOffset contains the size of a cell.    // Failure to specify this value will result in an error.    hr = pIAccessor->CreateAccessor(DBACCESSOR_ROWDATA, cBind, rgBind,                                    dwOffset, phAccessor, NULL);    pIAccessor->Release();    pIColumnsInfo->Release();    // Allocate a buffer for a single cell in a slice.    ULONG cbRowsize = dwOffset;    pData = (BYTE*)CoTaskMemAlloc(cbRowSize);    // Fetch each cell in the dataset.    for (ULONG ulCellCoord=0; ulCellCoord < ulMaxCoord; ulCellCoord++)    {       // Populate cell buffer.       hr = pIMDDataset->GetCellData(hAccessor, ulCellCoord, ulCellCoord,                                     pData);       // Traverse each bound cell property value for a single cell "row."       // Use pColumn to access each column's data values.       for (iBind=0; iBind < cBind; iBind++)       {          // Advance to the column value.          (COLUMNDATA*)pColumn = (COLUMNDATA *)(pData +                                  rgBind[iBind].obLength);          // pColumn->var points to the variant value.       }    }    // Free the accessor and rowset.    hr = pIAccessor->ReleaseAccessor(hAccessor, NULL);    hr = pIAccessor->Release();    hr = pIColumnsInfo->Release();    // Free the row data and bindings.    CoTaskMemFree(pData);    CoTaskMemFree(rgBind);    // Free the column info.    CoTaskMemFree(pInfo);    CoTaskMemFree(pwszStringsBuffer);    hr = pIMDDataset->FreeAxisInfo(cAxis, rgAxisInfo);    hr = pIMDDataset->Release();    return hr; }

1998-2001 Microsoft Corporation. All rights reserved.



Microsoft Ole Db 2.0 Programmer's Reference and Data Access SDK
Microsoft OLE DB 2.0 Programmers Reference and Data Access SDK (Microsoft Professional Editions)
ISBN: 0735605904
EAN: 2147483647
Year: 1998
Pages: 1083

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net