sql server2000表中的一个字段存储text类型数据,格式为每个数据间隔一个空格,即"3.0 4.4 5.9 6....."。现在自己封装一个getchunk函数,如下:
BOOL CADORecordset::GetChunk(FieldPtr pField, LPVOID lpData)
{
    long lngSize, lngOffSet = 0;
    _variant_t varChunk;    
    UCHAR chData;
    HRESULT hr;
    long lBytesCopied = 0;    lngSize = pField->ActualSize;

    while(lngOffSet < lngSize)
    { 
        varChunk = pField->GetChunk(ChunkSize);
        for(long lIndex = 0; lIndex <= (ChunkSize - 1); lIndex++)
        {
          hr= SafeArrayGetElement(varChunk.parray, &lIndex, &chData);     
          if(SUCCEEDED(hr))
          {
              hr = SafeArrayPutElement((SAFEARRAY FAR*)Data,              &lBytesCopied ,&chData); 
     ((UCHAR*)lpData)[lBytesCopied] = chData;
              lBytesCopied++;
           }
           else
              break;
         }
lngOffSet += ChunkSize;
    }
    lngOffSet = 0;
    return TRUE;
}
调试时发现到varChunk = pField->GetChunk(ChunkSize);时还是正确的,varChunk中保存了"3.0 4.4 5.9 6....."内容,但是SafeArrayGetElement(varChunk.parray, &lIndex, &chData);这句返回的hr为空。有大侠知道错在那里吗?

解决方案 »

  1.   

    你确认是在SafeArrayGetElement(varChunk.parray, &lIndex, &chData);这句返回的hr为空吗?
    我认为你应该把
    hr = SafeArrayPutElement((SAFEARRAY FAR*)Data,              &lBytesCopied ,&chData); 
    这一句去掉
      

  2.   

    换成下面的代码试试看:
    if(char *pBuffer = new char[ChunkSize+1]) ///重新申请必要的存储空间
    {
    char *pBuf = NULL;
    SafeArrayAccessData(varBLOB.parray,(void **)&pBuf);
    memcpy(pBuffer,pBuf,ChunkSize); ///复制数据到缓冲区m_pBMPBuffer
    SafeArrayUnaccessData (varBLOB.parray);
             ((UCHAR*)lpData)[lBytesCopied] = pBuf;
                  lBytesCopied++;
    }
      

  3.   

    To runall:确定的,所以和SafeArrayPutElement应该没有关系。
    To kyh77:试过了。在程序中
            hr = SafeArrayAccessData(varBLOB.parray,(void **)&pBuf);
            if (FAILED(hr))
       break;
            发现返回的hr还是不行,直接就break了。
      

  4.   

    我对sqlserver不太懂
    是不是text类型的数据根本就不用GetChunk,直接就可以读到_variant_t类型的变量中
      

  5.   

    // Copy the data only upto the Actual Size of Field.  
    for (long lIndex = 0; lIndex <= (ChunkSize - 1); lIndex++)
    {
        hr= SafeArrayGetElement(varChunk.parray, &lIndex, &chData);
        if (SUCCEEDED(hr))
        {
            // Take BYTE by BYTE and advance Memory Location
            // hr = SafeArrayPutElement((SAFEARRAY FAR*)lpData, &lBytesCopied ,&chData); 
    ((UCHAR*)lpData)[lBytesCopied] = chData;
            lBytesCopied++;
        }
        else
            break;
    }// hr = SafeArrayPutElement((SAFEARRAY FAR*)lpData, &lBytesCopied ,&chData); 
    去掉这个话!如果我没有猜错的话,你的这个类是Carlos Antollini 写的吧!
    这个类我也帮他改了些!
    他的那套现在只支持CLIENT游标,现在我给他改一个SERVER游标的功能!
      

  6.   

    谢谢ozzman,那句话确实应该去掉,但现在的问题是
    hr= SafeArrayGetElement(varChunk.parray, &lIndex, &chData);这句返回的hr无效,所以直接就break了
      

  7.   

    现在在varChunk = pField->GetChunk(ChunkSize);和
    for(long lIndex = 0; lIndex <= (ChunkSize - 1); lIndex++)之间加入
    if (varChunk.vt != (VT_ARRAY | VT_UI1))
    {
         return FALSE;
    }
    发现varChunk.vt != (VT_ARRAY | VT_UI1),函数在此返回。这是啥原因
      

  8.   

    外部调用如下:
      int n = 5;
      CString type = "fault";
      char buff[3000];   
      CString strQuery;
      strQuery.Format("select * from Alarm where address = %d and value = %s", n,   type);
      if(!m_AdoConnection.IsOpen())     //数据库是否打开
           OpenDatabase();
      CADORecordset* pRecord = new CADORecordset(&m_AdoConnection);//创建记录集
      pRecord->Open((LPCTSTR)strQuery, CADORecordset::openQuery); // 返回特定的记录
      if(pRecord->GetChunk("value", (char*)(LPVOID)buff))  // 读取返回记录中的录波数据
        ......
    程序调用的GetChunk函数定义如下:
    BOOL CADORecordset::GetChunk(LPCTSTR lpFieldName, LPVOID lpData)
    {
        FieldPtr pField = m_pRecordset->Fields->GetItem(lpFieldName);
        return GetChunk(pField, lpData);
    }
    GetChunk(pField, lpData);函数就是出问题的函数。
      

  9.   

    晕!你的buff是什么类型怎么是CHAR呢?
      

  10.   

    我在Carlos Antollini的贴子上有我写的方法,How to get binary field.
      

  11.   

    //step 1.
    BYTE *data;
    //step 2.
    data = new BYTE[size];
    //step 3.
    CYourADOClass->GetChunk("XXX", (LPVOID)data);
    //step 4.
    delete data
      

  12.   

    谢谢你的提醒,但现在到hr= SafeArrayGetElement(varChunk.parray, &lIndex, &chData);这句就出错了,还没涉及到data的类型呢。是不是数据库中字段的格式有问题:现在字段定义的是text格式,然后里面存的是字符串"1.0 2.0 3.0......."。
    我看Carlos Antollini的帖子中有appendchunk和getchunk的例子,如下://Sample of AppendChunck
    prs.AddNew();
    prs.SetFieldValue("ID", 5);
    prs.SetFieldValue("Description", "Client 05");
    prs.SetFieldValue("Checker", 1);
    prs.AppendChunk("Document", 
      "This Document is the story of Bob and his Friends...", 37);
    prs.Update();//Sample of GetChunck
    char data[1024];
    prs.GetChunk("Document", (LPVOID)&data);