我用api(不是MFC)编了一段用ado读取access数据库的程序,编译没出错,但运行时报错如下:
Runtome Error!
Program:E:\sample\access_ado.exe
abnormal program termination.
不知是怎么回事,有什么解决方法?这一段不加到消息队列里面只是在关闭窗口的时候报同样的错。程序片段如下:
_ConnectionPtr m_pConnection;
_RecordsetPtr m_pRecordset;
_variant_t var;
case WM_COMMAND:
wmId    = LOWORD(wParam); 
wmEvent = HIWORD(wParam); 
// Parse the menu selections:
switch (wmId)
{
case IDM_SHOW:
// 读入库中各字段并加入列表框中
try
{
                   while(!m_pRecordset->adoEOF)
{
/* var = m_pRecordset->GetCollect("Name");
if(var.vt != VT_NULL)
strName = (LPCSTR)_bstr_t(var);
var = m_pRecordset->GetCollect("Age");
if(var.vt != VT_NULL)
strAge = (LPCSTR)_bstr_t(var); m_AccessList.AddString( strName + " --> "+strAge );//api 里面好象不支持,该加什么头文件?*/
if(var.vt != VT_NULL)
{
var = m_pRecordset->GetCollect("Name");
strcpy(strName,(LPCSTR)_bstr_t(var));
}
m_pRecordset->MoveNext();
}
}
catch(_com_error *e)
{
// AfxMessageBox(e->ErrorMessage());//api里好象也不支持
MessageBox (NULL,e->ErrorMessage(), TEXT ("Error"), 0) ;
}     
break;      
     .
     .
     .
}

解决方案 »

  1.   

    我在WM_CREATE这个消息里进行了初始化。
    是不是这段程序不能在这里?如果不在这里写,产生消息,我要根据消息完成任务,该怎样得到消息呢?高手指点一下!
      

  2.   

    楼主的错误是用了一个没有正常操作_RecordsetPtr指针的错,可能情况:
    1、是否实例化了
    2、查询的表中是否确定有那些字段
    3、是否表中有记录
    4、该指针是否已经打开过,而没关闭
      

  3.   

    感谢 VCSQLVB(九龙.君威) 的回复!字段及记录都有。指针关闭了:
    case WM_DESTROY:
    m_pRecordset->Close();
    m_pRecordset = NULL;
    //~~~~~~~~~~~~~~~~~~~~~~~~~~~
    if(m_pConnection->State)
    m_pConnection->Close();
    m_pConnection= NULL;      
    CoUninitialize();
    PostQuitMessage(0);
    break;
    不知是不是应该在这里关闭?
    实例化是什么意思?我是边干边学,请指点一下!!!
    前面的操作是这样的:
    case WM_CREATE:
    //打开一个库连接
    // 初始化COM,创建ADO连接等操作
    CoInitialize(NULL);
    m_pConnection.CreateInstance(__uuidof(Connection)); try                 
    {
    // 打开本地Access库Demo.mdb
    m_pConnection->Open("Provider=Microsoft.Jet.OLEDB.4.0;Data Source=Demo.mdb","","",adModeUnknown);
    }
    catch(_com_error e)
    {
    MessageBox (NULL, TEXT ("数据库连接失败,确认数据库Demo.mdb是否在当前路径下!"), TEXT ("Error"), 0) ;
    return FALSE;
    }       m_pRecordset.CreateInstance(__uuidof(Recordset));//是它吗?           ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    try
    {
    m_pRecordset->Open("SELECT * FROM DemoTable",                // 查询DemoTable表中所有字段 m_pConnection.GetInterfacePtr(),  // 获取库接库的IDispatch指针
    adOpenDynamic,
    adLockOptimistic,
    adCmdText);
    }
    catch(_com_error *e)
    {
    MessageBox (NULL, e->ErrorMessage(), TEXT ("Error"), 0) ;
    }       if(!m_pRecordset->BOF)
    m_pRecordset->MoveFirst();
    else
    {
    MessageBox (NULL,TEXT("表内数据为空"), TEXT ("Error"), 0) ;
    return 0;
    }
      

  4.   

    if(var.vt != VT_NULL)
    这句改成
    if(V_VT(&var) != VT_NULL)试试
      

  5.   

    void CMemberDlg::OnDestroy() 
    {

    CDialog::OnDestroy();

    // TODO: Add your message handler code here
    if(m_pRs->State)
    m_pRs->Close();
    m_pRs.Release();
    if(m_pCon->State)
    m_pCon->Close();
    m_pCon.Release(); ::CoUninitialize();  //释放COM占用的资源
    }
      

  6.   

    结果还是一样的
    m_pRs.Release();和m_pRs = NULL;的效果应该是一样的吧!
    还有我是用的API不是MFC。
      

  7.   

    if(m_pCon->State)改为if(m_pCon->State==adStateOpen)
    都改掉  试看看~
      

  8.   

    还有void CMemberDlg::OnDestroy() 里的CDialog::OnDestroy();应该放在最后~
    原因可能就在这里~试试看!
      

  9.   

    谢谢大家的支持。我现在精简了一下程序,方便阅读。希望大家给我更多的支持!解决完问题后我会另外加分的!!!!!!!
    我用api(不是MFC)编了一段用ado读取access数据库的程序,编译没出错,但运行时报错如下:
    Runtome Error!
    Program:E:\sample\access_ado.exe
    abnormal program termination.
    程序片段如下:
    _ConnectionPtr m_pConnection;
    _RecordsetPtr m_pRecordset;
    _variant_t var; case WM_CREATE:
    //打开一个库连接
    CoInitialize(NULL);
    m_pConnection.CreateInstance(__uuidof(Connection)); m_pConnection->Open("Provider=Microsoft.Jet.OLEDB.4.0;Data Source=Demo.mdb","","",adModeUnknown);
    //打开表
                    m_pRecordset.CreateInstance(__uuidof(Recordset));
    m_pRecordset->Open("SELECT * FROM DemoTable",m_pConnection.GetInterfacePtr(),adOpenDynamic,adLockOptimistic,adCmdText);    
    case WM_COMMAND:
    wmId    = LOWORD(wParam); 
    wmEvent = HIWORD(wParam); 
    // Parse the menu selections:
    switch (wmId)
    {
    case IDM_SHOW:
    // 读入库中各字段并加入列表框中
                       while(!m_pRecordset->adoEOF)
    { if(var.vt != VT_NULL)
    {
    var = m_pRecordset->GetCollect("Name");
    strcpy(strName,(LPCSTR)_bstr_t(var));
    }
    m_pRecordset->MoveNext();
    }
    }
    //关闭连接
    case WM_DESTROY:
    if(m_pRecordse->State)
    m_pRecordset->Close();
    m_pRecordset = NULL;
    if(m_pConnection->State)
    m_pConnection->Close();
    m_pConnection= NULL;      
    CoUninitialize();
    PostQuitMessage(0);
      

  10.   

    是不是你的程序流程有问题,
    每次m_pRecordset->Open()操作后都应该要关闭m_pRecordset,你检查一下
      

  11.   

    就是说RecordSet对象每次调用了Open方法后,要再调用Open方法获得另外一个数据集,就必须把先前的数据集用Close方法关闭后才能Open。当然,如果用Command对象来获得数据集RecordSet就不用这么麻烦了,不过好像大家都喜欢直接用Open方法
      

  12.   

    最好用 (LPCSTR)(_bstr_t)m_pRec->GetCollect() 来转换数据到 CSTRING类型