用ADO的数据集类RECORDSET的GetCollect函树取得数据库的非空记录时是没有错误的但当记录为空时记录集就会发出错误,我的问题是在如何判断数据库的记录为空.

解决方案 »

  1.   

    刚打开时用bof判断。true则为空……
      

  2.   

    在ADO中,我想这三个应该对你有用
    针对打开的一个记录集
        RecordCount属性表示改打开记录集的记录总数
        EOF:游标是否处于最后一条记录之后,true值为(-1)false值为(0)
        BOF:游标是否处于的一条记录之前,后面同上
      

  3.   

    if(m_pRecordset->GetCollect("comment").vt!=VT_NULL)
    {
    ....}
      

  4.   

    谢谢 hoco(流星雨) 的语句我试一试看行不行.
      

  5.   

    hoco(流星雨)这段代码不行如果数据库的记录为空,就不能执行
    m_pRecordset->GetCollect("comment")否则会抛出错误.这样此语句以下的代码就不会行回转到Catch语句.
    能不能在执行这句之前判断记录为空.
      

  6.   

    // 给你一个例子
    while ( !pRecordset->adoEOF )
    {
    _variant_t theValue;
    theValue = pRecordset->GetCollect("comment"); if ( theValue.vt != VT_NULL ) 
    {
       // 你的处理
    }
    pRecordset->MoveNext();
    }
      

  7.   

    我今天上午刚看了别人的一段代码,也有你说的同样的问题,我加了一个if就解决问题了,方法同darkwing() loze(乐子) 说的差不多:
    if(!m_pRst->IsBOF())(可能是这样的吧)
      

  8.   

    就这个问题还有争议吗?  ahphone(根号6.0),你发现我的错误了???
    joer98656 try
      

  9.   

    为空时可以添加的。
    各位感觉 ADO好用还是OLE DB好用?
      

  10.   

    to 大家,if(!m_pRst->IsBOF())这样只是判断记录集对象指没指向最后一条
    记录, 我想知道的是怎样在执行pRecordset->GetCollect("comment")语句之前判断comment字段在数据库里是否为空.如果字段为空,再执行那一句的话就会产生错误.难道没有人知道吗!!!都这么多的UP了.
    继续等待,解决者立刻加班100分!!!
      

  11.   

    to  joer986565:
       你不读当前记录,就能判断字段为空 ??
    你试过我的例子没有#import "c:\program files\common files\system\ado\msado15.dll" \
          rename ( "EOF", "adoEOF" )
      

  12.   

    我记得我以前这么用,是能够判出字段是否为空的,前提当前记录必须有,从前往后读时要判是否到尾部 while ( !pRecordset->adoEOF )
      

  13.   

    _variant_t value;
    CString strvalue;value=(*rs)->GetCollect("value");
    strvalue=(value.vt!=VT_NULL) ? (char*)(_bstr_t)value : "";这样就可以了,我试过了,没问题,你试一下。
      

  14.   

    另外还有一种方法:你可以试试 (来源于MSDN)
    http://msdn.microsoft.com/code/default.asp?url=/msdn-files/026/000/217/readme_txt.aspvariant_t v(rs->Fields->Item[_variant_t("StudName")]->Value);
       if( v.vt == VT_NULL)再不行,你去骂MSDN吧
      

  15.   

    另外,if(!m_pRst->IsBOF())
    常在使用MovePrevious时用,MoveNext要判尾巴
      

  16.   

    to   sunbo()   hoco(流星雨)  
    我要给分了,其他人每人2分.
    你俩再回复接一下.不好意思  sunbo()   hoco(流星雨)  的回答没有错.
    原来错误不是出现在theValue = pRecordset->GetCollect("comment")
    而是出现在将 theValue 的值负给其它变量时出错,比如负给一个字符串时.那么为什么不能负给其它变量呢?还得在负之前判断是否为空.
    其它数据库技术也是这样吗?如ODBC,DAO.
      

  17.   

    试一下
    CString strResult = " ";
    while ( !pRecordset->adoEOF )
    {
    _variant_t theValue;
    theValue = pRecordset->GetCollect("comment"); if ( theValue.vt != VT_NULL ) 
    {
    theValue.ChangeType(VT_BSTR);
    strResult = theValue.bstrval;
    }
    pRecordset->MoveNext();
    }
      

  18.   


    strResult = theValue.bstrval;
    改为
    strResult = theValue.bstrVal;
      

  19.   

    把取出来的值赋给_variant_t变量,用变体变量来判断否NULL,
    还有,ADO中的函数返回值很多都是变体(_variant_t)类型,
    所以像CString m_strName=m_pRecordset->GetCollect("name");是行不通的,因为类型不同,系统又无法帮你转换。
    COleVariant功能很强大,以后不防都用它来存放ADO中的部分返回值(某一字段的值),下面是一个COleVariant到CString的转换函数,作者是谁忘了,贴出来让大家看看
    CString VariantToStr(const COleVariant& var)
    {
    CString strRet;
    strRet = _T("Fish");
    switch(var.vt){
    case VT_EMPTY:
    case VT_NULL:
    strRet = _T("");
    break;
    case VT_I2:
    strRet.Format(_T("%hd"),V_I2(&var));
    break;
    case VT_I4:
    strRet.Format(_T("%d"),V_I4(&var));
    break;
    case VT_R4:
    strRet.Format(_T("%e"),(double)V_R4(&var));
    break;
    case VT_R8:
    strRet.Format(_T("%e"),V_R8(&var));
    break;
    case VT_CY:
    strRet = COleCurrency(var).Format();
    break;
    case VT_DATE:
    strRet = COleDateTime(var).Format(_T("%m %d %y"));
    break;
    case VT_BSTR:
    // strRet = V_BSTRT(&var);
    strRet =(char *)_bstr_t(var);
    break;
    case VT_DISPATCH:
    strRet = _T("VT_DISPATCH");
    break;
    case VT_ERROR:
    strRet = _T("VT_ERROR");
    break;
    case VT_BOOL:
    return V_BOOL(&var) ? _T("TRUE") : _T("FALSE");
    case VT_VARIANT:
    strRet = _T("VT_VARIANT");
    break;
    case VT_UNKNOWN:
    strRet = _T("VT_UNKNOWN");
    break;
    case VT_I1:
    strRet = _T("VT_I1");
    break;
    case VT_UI1:
    strRet.Format(_T("0x%02hX"),(unsigned short)V_UI1(&var));
    break;
    case VT_UI2:
    strRet = _T("VT_UI2");
    break;
    case VT_UI4:
    strRet = _T("VT_UI4");
    break;
    case VT_I8:
    strRet = _T("VT_I8");
    break;
    case VT_UI8:
    strRet = _T("VT_UI8");
    break;
    case VT_INT:
    strRet = _T("VT_INT");
    break;
    case VT_UINT:
    strRet = _T("VT_UINT");
    break;
    case VT_VOID:
    strRet = _T("VT_VOID");
    break;
    case VT_HRESULT:
    strRet = _T("VT_HRESULT");
    break;
    case VT_PTR:
    strRet = _T("VT_PTR");
    break;
    case VT_SAFEARRAY:
    strRet = _T("VT_SAFEARRAY");
    break;
    case VT_CARRAY:
    strRet = _T("VT_CARRAY");
    break;
    case VT_USERDEFINED:
    strRet = _T("VT_USERDEFINED");
    break;
    case VT_LPSTR:
    strRet = _T("VT_LPSTR");
    break;
    case VT_LPWSTR:
    strRet = _T("VT_LPWSTR");
    break;
    case VT_FILETIME:
    strRet = _T("VT_FILETIME");
    break;
    case VT_BLOB:
    strRet = _T("VT_BLOB");
    break;
    case VT_STREAM:
    strRet = _T("VT_STREAM");
    break;
    case VT_STORAGE:
    strRet = _T("VT_STORAGE");
    break;
    case VT_STREAMED_OBJECT:
    strRet = _T("VT_STREAMED_OBJECT");
    break;
    case VT_STORED_OBJECT:
    strRet = _T("VT_STORED_OBJECT");
    break;
    case VT_BLOB_OBJECT:
    strRet = _T("VT_BLOB_OBJECT");
    break;
    case VT_CF:
    strRet = _T("VT_CF");
    break;
    case VT_CLSID:
    strRet = _T("VT_CLSID");
    break;
    }
    return strRet;
    }
      

  20.   

    ado 是很好用,但太麻烦,各位有没有用过ado X
      

  21.   

    关注,更正我前面的发言,以免误导别人!
    我在前面说RecordCount表示打开记录集的记录个数,有个前提条件:
    打开记录的的光标类型是adOpenStatic和,adOpenKeyset两种,
    另外两种adOpenDynamic和,adOpenForwardOnly其返回值为-1!