新人求助???MFC ADO方式连接SQL server数据库读取并显示在listcontrol出错??

积硅步至千里. 2016-08-09 05:06:33
很简单的问题我却折腾了一周了,之前没用过SQL,第一次做访问数据库的实例。
网上找了很多参考。贴上代码:
首先建立MFC对话框工程,添加listcontrol;
在theAPP.h声明 _ConnectionPtr m_pConnection;
在theAPP.cpp函数InitInstance()添加:
AfxOleInit();
m_pConnection.CreateInstance(__uuidof(Connection));
try
{
m_pConnection->ConnectionString = "Driver={SQL server};server=USER-20160714BG;uid=sa;pwd=123456;database=student";
m_pConnection->Open("","","",adConnectUnspecified);
}
catch(_com_error e)
{
AfxMessageBox(L"数据库连接失败,确认数据库Demo.mdb是否在当前路径下!");
return FALSE;
}

然后Dlg.h声明
_CommandPtr   m_pCommand;
_RecordsetPtr m_pRecordset;
Dlg.cpp的OnInitDialog()
DWORD dwStyle; // 设置新风格
dwStyle=m_list.GetExtendedStyle();
dwStyle|=LVS_EX_GRIDLINES | LVS_EX_FULLROWSELECT;
m_list.SetExtendedStyle(dwStyle);

//初始化ListControl控件的各个列
m_list.InsertColumn(0,L"id",LVCFMT_CENTER,60);
m_list.InsertColumn(1,L"name",LVCFMT_CENTER,60);
m_list.InsertColumn(2,L"wage",LVCFMT_CENTER,60);

然后添加button控件 并添加事件处理函数,
UpdateData();
m_list.DeleteAllItems();
CString SQL,id,name,wage;
SQL.Format(L"select * from wage by id");

m_pRecordset=theApp.m_pConnection->Execute((_bstr_t)SQL,NULL,adCmdText);
int Counter=0;
if(!(m_pRecordset->BOF))
{
m_pRecordset->MoveFirst();
while (!m_pRecordset->adoEOF)

{
id =(char*)(_bstr_t)m_pRecordset->GetCollect(L"id");
name=(char*)(_bstr_t)m_pRecordset->GetCollect(L"name");
wage=(char*)(_bstr_t)m_pRecordset->GetCollect(L"wage");


m_list.InsertItem(Counter,0);

m_list.SetItemText(Counter,0,id);
m_list.SetItemText(Counter,1,name);//同上
m_list.SetItemText(Counter,2,wage);

m_pRecordset->MoveNext();
Counter++;
}
}
UpdateData(false);

编译没问题,应该连上了数据库;当点击查询按钮时出错了

...全文
490 11 打赏 收藏 转发到动态 举报
写回复
用AI写文章
11 条回复
切换为时间正序
请发表友善的回复…
发表回复
  • 打赏
  • 举报
回复
m_pRecordset->Open("SELECT * FROM student",m_pConnection.GetInterfacePtr(),adOpenDynamic,adLockOptimistic,adCmdText);
  • 打赏
  • 举报
回复
谢谢大家,在打开记录集的地方出问题了,应当
m_pRecordset->Open("SELECT * FROM student",m_pConnection.GetInterfacePtr(),adOpenDynamic,adLockOptimistic,adCmdText);
qq_35961050 2016-08-25
  • 打赏
  • 举报
回复
这类问题一般出在数据库自身的问题,建议你重新建个表,然后把表名和参数也换一下
  • 打赏
  • 举报
回复
引用 5 楼 zgl7903 的回复:
try catch 捕捉 _com_error 异常

//范例: 带 Extensions 的 ADO
//该程序说明了如何从字段检索数值并将数值转换为 C++ 变量。它包括了在程序段(范例:无 Extensions 的 ADO)中所描述的功能。

#define INITGUID
#import "c:\Program Files\Common Files\System\ADO\msado15.dll" 
   no_namespace rename("EOF", "EndOfFile")
#include <stdio.h>
#include "icrsint.h"

void dump_com_error(_com_error &e)
   {
printf("Error\n");
printf("\a\tCode = %08lx\n", e.Error());
printf("\a\tCode meaning = %s", e.ErrorMessage());
_bstr_t bstrSource(e.Source());
_bstr_t bstrDescription(e.Description());
printf("\a\tSource = %s\n", (LPCSTR) bstrSource);
printf("\a\tDescription = %s\n", (LPCSTR) bstrDescription);
   }

class CCustomRs : 
   public CADORecordBinding
{
BEGIN_ADO_BINDING(CCustomRs)
   ADO_VARIABLE_LENGTH_BINDING_ENTRY(1, adVarChar, m_szau_lname, 
         sizeof(m_szau_lname), lau_lnameStatus, FALSE)
   ADO_VARIABLE_LENGTH_BINDING_ENTRY(2, adVarChar, m_szau_fname, 
         sizeof(m_szau_fname), lau_fnameStatus, TRUE)
END_ADO_BINDING()

public:
   CHAR   m_szau_lname[41];
   ULONG   lau_lnameStatus;
   CHAR   m_szau_fname[41];
   ULONG   lau_fnameStatus;
};

VOID   main()
   {
   HRESULT hr;
   IADORecordBinding   *picRs = NULL;
   
   ::CoInitialize(NULL);

   try 
      {
      _RecordsetPtr pRs.CreateInstance(__uuidof(Recordset));      CCustomRs rs;
      
      pRs->Open("select FirstName, LastName, Age from Employees", 
         "dsn=pubs;uid=sa;pwd=;", 
         adOpenStatic, adLockOptimistic, adCmdUnknown);
      
      if (FAILED(hr = pRs->QueryInterface(__uuidof(IADORecordBinding), 
            (LPVOID*)&picRs)))
         _com_issue_error(hr);
      
      if (FAILED(hr = picRs->BindToRecordset(&rs)))
         _com_issue_error(hr);

      while (VARIANT_FALSE == pRs->EndOfFile)
         {
      // 处理 CCustomRs C++ 实例变量中的数据。

         printf("\a\tName = %s \t%s", 
            (lau_fnameStatus == adFldOK ? m_szau_fname : "<NULL>"), 
            (lau_lnameStatus == adFldOK ? m_szau_lname): "<NULL>"));

      // 更改 Recordset 的当前行。
      // 新当前行的 Recordset 数据将被
      // 自动取出并防止在 CCustomRs C++ 实例变量中
   
         pRs->MoveNext();
         }
      }
   catch (_com_error &e)
      {
      dump_com_error(e);
      }

   if (picRs)
      picRs->Release();

   CoUninitialize();
   };


我之前采用ODBC 方式连接过数据库,配置了及其数据源,对ADO方式有没有影响?
  • 打赏
  • 举报
回复
引用 5 楼 zgl7903 的回复:
try catch 捕捉 _com_error 异常

//范例: 带 Extensions 的 ADO
//该程序说明了如何从字段检索数值并将数值转换为 C++ 变量。它包括了在程序段(范例:无 Extensions 的 ADO)中所描述的功能。

#define INITGUID
#import "c:\Program Files\Common Files\System\ADO\msado15.dll" 
   no_namespace rename("EOF", "EndOfFile")
#include <stdio.h>
#include "icrsint.h"

void dump_com_error(_com_error &e)
   {
printf("Error\n");
printf("\a\tCode = %08lx\n", e.Error());
printf("\a\tCode meaning = %s", e.ErrorMessage());
_bstr_t bstrSource(e.Source());
_bstr_t bstrDescription(e.Description());
printf("\a\tSource = %s\n", (LPCSTR) bstrSource);
printf("\a\tDescription = %s\n", (LPCSTR) bstrDescription);
   }

class CCustomRs : 
   public CADORecordBinding
{
BEGIN_ADO_BINDING(CCustomRs)
   ADO_VARIABLE_LENGTH_BINDING_ENTRY(1, adVarChar, m_szau_lname, 
         sizeof(m_szau_lname), lau_lnameStatus, FALSE)
   ADO_VARIABLE_LENGTH_BINDING_ENTRY(2, adVarChar, m_szau_fname, 
         sizeof(m_szau_fname), lau_fnameStatus, TRUE)
END_ADO_BINDING()

public:
   CHAR   m_szau_lname[41];
   ULONG   lau_lnameStatus;
   CHAR   m_szau_fname[41];
   ULONG   lau_fnameStatus;
};

VOID   main()
   {
   HRESULT hr;
   IADORecordBinding   *picRs = NULL;
   
   ::CoInitialize(NULL);

   try 
      {
      _RecordsetPtr pRs.CreateInstance(__uuidof(Recordset));      CCustomRs rs;
      
      pRs->Open("select FirstName, LastName, Age from Employees", 
         "dsn=pubs;uid=sa;pwd=;", 
         adOpenStatic, adLockOptimistic, adCmdUnknown);
      
      if (FAILED(hr = pRs->QueryInterface(__uuidof(IADORecordBinding), 
            (LPVOID*)&picRs)))
         _com_issue_error(hr);
      
      if (FAILED(hr = picRs->BindToRecordset(&rs)))
         _com_issue_error(hr);

      while (VARIANT_FALSE == pRs->EndOfFile)
         {
      // 处理 CCustomRs C++ 实例变量中的数据。

         printf("\a\tName = %s \t%s", 
            (lau_fnameStatus == adFldOK ? m_szau_fname : "<NULL>"), 
            (lau_lnameStatus == adFldOK ? m_szau_lname): "<NULL>"));

      // 更改 Recordset 的当前行。
      // 新当前行的 Recordset 数据将被
      // 自动取出并防止在 CCustomRs C++ 实例变量中
   
         pRs->MoveNext();
         }
      }
   catch (_com_error &e)
      {
      dump_com_error(e);
      }

   if (picRs)
      picRs->Release();

   CoUninitialize();
   };


try catch 捕捉异常,那我怎么改呢
  • 打赏
  • 举报
回复
引用 4 楼 maverick432 的回复:
能不能上传一下完整的工程和数据库文件,我调试一下试试
怎么上传??要不你留下扣扣,我发给你
zgl7903 2016-08-10
  • 打赏
  • 举报
回复
try catch 捕捉 _com_error 异常

//范例: 带 Extensions 的 ADO
//该程序说明了如何从字段检索数值并将数值转换为 C++ 变量。它包括了在程序段(范例:无 Extensions 的 ADO)中所描述的功能。

#define INITGUID
#import "c:\Program Files\Common Files\System\ADO\msado15.dll" 
   no_namespace rename("EOF", "EndOfFile")
#include <stdio.h>
#include "icrsint.h"

void dump_com_error(_com_error &e)
   {
printf("Error\n");
printf("\a\tCode = %08lx\n", e.Error());
printf("\a\tCode meaning = %s", e.ErrorMessage());
_bstr_t bstrSource(e.Source());
_bstr_t bstrDescription(e.Description());
printf("\a\tSource = %s\n", (LPCSTR) bstrSource);
printf("\a\tDescription = %s\n", (LPCSTR) bstrDescription);
   }

class CCustomRs : 
   public CADORecordBinding
{
BEGIN_ADO_BINDING(CCustomRs)
   ADO_VARIABLE_LENGTH_BINDING_ENTRY(1, adVarChar, m_szau_lname, 
         sizeof(m_szau_lname), lau_lnameStatus, FALSE)
   ADO_VARIABLE_LENGTH_BINDING_ENTRY(2, adVarChar, m_szau_fname, 
         sizeof(m_szau_fname), lau_fnameStatus, TRUE)
END_ADO_BINDING()

public:
   CHAR   m_szau_lname[41];
   ULONG   lau_lnameStatus;
   CHAR   m_szau_fname[41];
   ULONG   lau_fnameStatus;
};

VOID   main()
   {
   HRESULT hr;
   IADORecordBinding   *picRs = NULL;
   
   ::CoInitialize(NULL);

   try 
      {
      _RecordsetPtr pRs.CreateInstance(__uuidof(Recordset));      CCustomRs rs;
      
      pRs->Open("select FirstName, LastName, Age from Employees", 
         "dsn=pubs;uid=sa;pwd=;", 
         adOpenStatic, adLockOptimistic, adCmdUnknown);
      
      if (FAILED(hr = pRs->QueryInterface(__uuidof(IADORecordBinding), 
            (LPVOID*)&picRs)))
         _com_issue_error(hr);
      
      if (FAILED(hr = picRs->BindToRecordset(&rs)))
         _com_issue_error(hr);

      while (VARIANT_FALSE == pRs->EndOfFile)
         {
      // 处理 CCustomRs C++ 实例变量中的数据。

         printf("\a\tName = %s \t%s", 
            (lau_fnameStatus == adFldOK ? m_szau_fname : "<NULL>"), 
            (lau_lnameStatus == adFldOK ? m_szau_lname): "<NULL>"));

      // 更改 Recordset 的当前行。
      // 新当前行的 Recordset 数据将被
      // 自动取出并防止在 CCustomRs C++ 实例变量中
   
         pRs->MoveNext();
         }
      }
   catch (_com_error &e)
      {
      dump_com_error(e);
      }

   if (picRs)
      picRs->Release();

   CoUninitialize();
   };


maverick432 2016-08-09
  • 打赏
  • 举报
回复
能不能上传一下完整的工程和数据库文件,我调试一下试试
  • 打赏
  • 举报
回复
引用 1 楼 VisualEleven 的回复:
你自己Debug模式下单步调试一下,看看哪句执行失败了?


F10逐句调试的,在theApp.cpp 和Dlg.cpp分别设置了断点,当从BOOL CADO3Dlg::OnInitDialog() 函数跳到dlgcore.cppINT_PTR CALLBACK AfxDlgProc(HWND hWnd, UINT message, WPARAM, LPARAM)
{
if (message == WM_INITDIALOG)
{
// special case for WM_INITDIALOG
CDialog* pDlg = DYNAMIC_DOWNCAST(CDialog, CWnd::FromHandlePermanent(hWnd));
if (pDlg != NULL)
return pDlg->OnInitDialog();
else
return 1;
}
return 0;
}时显示
版主大哥,这是什么情况啊
赵4老师 2016-08-09
  • 打赏
  • 举报
回复
崩溃的时候在弹出的对话框按相应按钮进入调试,按Alt+7键查看Call Stack即“调用堆栈”里面从上到下列出的对应从里层到外层的函数调用历史。双击某一行可将光标定位到此次调用的源代码或汇编指令处,看不懂时双击下一行,直到能看懂为止
Eleven 2016-08-09
  • 打赏
  • 举报
回复
你自己Debug模式下单步调试一下,看看哪句执行失败了?

4,011

社区成员

发帖
与我相关
我的任务
社区描述
VC/MFC 数据库
社区管理员
  • 数据库
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧