本人用VC+ADO+SQL2008做了一个用完成端口写的大规响应程序,数据库的查询很频繁,经常会出现用同一条查询语句有时却不能正确返回记录,但是数据库中是有这一条记录的,该程序是多线程工作的,工作线程的数据库操作大致如下://数据库连接是全局变量,程序初始化的时候就正常连接到数据库了
_ConnectionPtr g_DBConnPtr;//以下为工作线程中数据库操作流程,XXXX表示用户名,YYYY表示密码
_RecordsetPtr MySet;
MySet.CreateInstance(__uuidof(Recordset));…………省略
try
{
    CString strSQL = _T("select * from UserInfo where Username='XXXX' and Password='YYYY'");
    MySet->Open((LPTSTR)strSQL.GetBuffer(), adOpenStatic, adLockOptimistic, adCmdText);
    if(MySet->GetRecordCount() == 0)
    {
        //问题就出在这里了,同样的用户名和密码查询,绝大部情况下都能正确得到记录,
        //但是有时还是出现查不到记录的情况,又没有catch到错误
        MySet->Close()
        continue;
    }
    //处理一些数据后关闭对象,注意,这里的处理只是读取某些字段的值,并没有进行修改
    MySet->Close()
    //增加登录次数计数
    strSQL = _T("update UserInfo set Times=Times+1 where Username='XXXX' and Password='YYYY'");
    g_DBConnPtr->Execute(strSQL.GetBuffer(), NULL, adCmdText);
}
catch(...)
{
    //报错
}
…………省略情况就是样了,头都想破了,也不知道哪里出了问题,难道是多个线程共用一个数据库连接的问题么?但是我写了一个测试程序,同时启动四个线程用同一条查询语句查询却没有出现以上的情况。
请教下各位高手,这是什么原因呢?最开始该程序用的是ACCESS,却没有这样的问题,移植到SQL Server就出这情况了。

解决方案 »

  1.   

    用GetRecordCount().MySet,g_DBConnPtr中游标CursorLocation 是设为adUseClient吗
      

  2.   

    你把异常错误信息打印出来不就知道什么错误了
    try
    {
    ...
    }
    catch(_com_error &e)
    {
    TRACE(_T("ErrorMessage: %s, Desc: %s\n"), e.ErrorMessage(), e.Description());
    }
      

  3.   

    zwfgdlc是正确,ACCESS的游标默认是客户端的,在移植到SQL Server没有考虑到。
    另外在操作的代码是用try-catch包围的,GetRecordCount()时并没有产生异常,按照zwfgdlc的建议,返回记录数是正确了,但是记录的Open偶尔会产生异常,ErrorMessage是未指定错误,Description竟然是乱码。
      

  4.   

    先判断OPEN是否成功,然后把if(MySet->GetRecordCount() == 0)改成~if(MySet->GetRecordCount() <1)
      

  5.   

    判断是不是到了AdoEof,再读取数据.
      

  6.   

    读取数据部分的代码是没有问题的,现在记录数返回没有问题了,就是MySet->Open这一条语句偶尔会有异常产生,很是奇怪