IRow::Open と ISequentialStream を使用した BLOB データのフェッチ

IRow::Open は、DBGUID_STREAM 型と DBGUID_NULL 型のオブジェクトを開くことだけをサポートします。

次の関数では、IRow::OpenISequentialStream を使用して大きなデータをフェッチします。

void InitializeAndExecuteCommand()
{
    ULONG iidx;
    WCHAR* wCmdString=OLESTR("SELECT * FROM MyTable");
    // Do the initialization, create the session, and set command text.
    hr = pICommandText->Execute(NULL, IID_IRow, NULL, 
                         &cNumRows,(IUnknown **)&pIRow)))
    //Get 1 column at a time.
    for(ULONG i=1; i <= NoOfColumns; i++)
      GetSequentialColumn(pIRow, iidx);
    // Do the clean up.
}
HRESULT GetSequentialColumn(IRow* pUnkRow, ULONG iCol)
{
    HRESULT hr = NOERROR;
    ULONG cbRead = 0;
    ULONG cbTotal = 0;
    ULONG cColumns = 0;
    ULONG cReads = 0;
    ISequentialStream* pIStream = NULL;
    WCHAR* pBuffer[kMaxBuff]; //50 chars read by ISequentialStream::Read()
    DBCOLUMNINFO* prgInfo;
    OLECHAR* pColNames;
    IColumnsInfo* pIColumnsInfo;
    DBID columnid;
    DBCOLUMNACCESS column;

    hr = pUnkRow->QueryInterface(IID_IColumnsInfo, 
                            (void**) &pIColumnsInfo);
    hr = pIColumnsInfo->GetColumnInfo(&cColumns, &prgInfo, &pColNames);
    // Get Column ID.
    columnid = (prgInfo + (iCol - 1))->columnid;
    // Get sequential stream object by calling IRow::Open.
    hr = pUnkRow->Open(NULL, &columnid, DBGUID_STREAM, 0, 
                    IID_ISequentialStream,(LPUNKNOWN *)&pIStream);
    ZeroMemory(pBuffer, kMaxBuff * sizeof(WCHAR));
    // Read 50 chars at a time until no more data.
    do
    {
        hr = pIStream->Read(pBuffer, kMaxBuff, &cbRead);
        cbTotal = cbTotal + cbRead;
        // Process the data.
    } while(cbRead > 0);
// Do the clean up.
    return hr;
}

大きなデータは、ISequentialStream インターフェイスを使用してバインドまたは取得できます。バインドされた列の場合、DBSTATUS_S_TRUNCATED を設定してデータが切り捨てられるかどうかが状態フラグで示されます。