Creating a Dataset and Obtaining Axis Information

OLE DB Programmer's Reference

This function executes an MDX query statement specified by pwszQuery. IMDDataset::GetAxisInfo and IMDDataset::GetAxisRowset are called to traverse the column information for each axis in the MDX query.

HRESULT MDPQueryColumnInfo(ICommandText *pICommandText, pwszQuery) {    HRESULT hr;    struct COLUMNDATA    {       SDWORD     dwLength;      // length of data       DBSTATUS   dwStatus;      // status of column       SHORT      wPadding;       BYTE       bData[1];      // variable-length data    };    // Execute the query.    IMDDataset* pIMDDataset = NULL;    hr = pICommandText->SetCommandText(DBGUID_MDX, pwszQuery);    hr = pICommandText->Execute(NULL, IID_IMDDataset, NULL, NULL,                                (IUnknown **)&pIMDDataset ));    // Fetch and traverse the axis info.    ULONG cAxis;    MDAXISINFO* rgAxisInfo = NULL;    hr = pIMDDataset->GetAxisInfo( &cAxis, &rgAxisInfo );    for (ULONG iAxis=0; iAxis < cAxis; iAxis++)    {    // rgAxisInfo contains the array of dimensions for each axis.    for (ULONG iDim=0; iDim <  rgAxisInfo[iAxis].cDimensions; iDim++)    {       // MDAXISINFO_GETAT(rgAxisInfo, iAxis).rgpwszDimensionNames points       // to the dimension name.       assert( MDAXISINFO_GETAT(rgAxisInfo, iAxis).rgpwszDimensionNames);    }       // Fetch the axis rowset for each axis.       IRowset* pIrowset = NULL;       hr = pIMDDataset->GetAxisRowse(NULL, iAxis,          IID_IRowset, 0, NULL, (IUnknown**)&pIRowset));       // Fetch the column info for the axis rowset.       IColumnsInfo *pIColumnsInfo = NULL;       hr = pIRowset->QueryInterface(IID_IColumnsInfo,          (void**)&pIColumnsInfo);       ULONG cCol;       WCHAR* pStringsBuffer = NULL;       DBCOLUMNINFO* pInfo = NULL;       hr = pIColumnsInfo->GetColumnInfo(&cCol, &pInfo, &pStringsBuffer);       // Create bindings for all columns, in same order as given by       // GetColumnInfo. Bind everything as string, and skip DBTYPE_VECTOR       // type columns.       ULONG dwOffset = 0;       ULONG iBind = 0;       ULONG cBind = 0;       DBBINDING* rgBind = (DBBINDING*)CoTaskMemAlloc(                            cCol*sizeof(DBBINDING));       for (ULONG iCol=0; iCol < cCol; iCol++)       {          // Skip columns of type _VECTOR (probably binary data).          if (pInfo[iCol].wType & DBTYPE_VECTOR)             continue;          rgBind[iBind].iOrdinal    = pInfo[iCol].iOrdinal;          rgBind[iBind].obValue     = dwOffset +             offsetof(COLUMNDATA,bData);          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    = pInfo[iCol].ulColumnSize;          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].bPrecision  = 0;          rgBind[iBind].bScale      = 0;          rgBind[iBind].wType       = DBTYPE_STR;          dwOffset += rgBind[iBind].cbMaxLen +             offsetof(COLUMNDATA,bData);          iBind++;       }       cBind = iBind;       // Create the accessor.       IAccessor* pIAccessor;       hr = pIRowset->QueryInterface(IID_IAccessor, (void**)&pIAccessor);       hr = pIAccessor->CreateAccessor(DBACCESSOR_ROWDATA, cBind, rgBind,                                       dwOffset, phAccessor, NULL);       // Allocate a buffer for a single row of data.       ULONG cbRowsize = dwOffset;       BYTE* pData = (BYTE *)CoTaskMemAlloc(cbRowSize);       while (SUCCEEDED(hr))       {          // Prepare internal buffers and get handles to the rows.          // Fetch 20 rows at a time.          ULONG cRowsObtained;          hr = pIRowset->GetNextRows(NULL, 0, 20, &cRowsObtained, &pRows);          // Break on EndOfRowset.          if (cRowsObtained == 0)   break;          for (ULONG iRow=0; iRow < cRowsObtained; iRow++)          {             // Clear buffer.             memset(pData, 0, cbRowSize);             // Get the row data.             hr = pIRowset->GetData(rghRows[iRow], hAccessor, pData);             // Traverse each bound column value for a single 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);                // (WCHAR*)pColumn->bData points to the string value.              }          }          // Release the row handles.          hr = pIRowset->ReleaseRows(cRowsObtained, rghRows, NULL, NULL,                                     NULL);       }       // Free the accessor and rowset.       hr = pIAccessor->ReleaseAccessor(hAccessor, NULL);       hr = pIAccessor->Release();       hr = pIRowset->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