ADO+MFC数据库编程常用SQL语句

本文详细介绍了数据库的增删改查操作,包括初始化COM和ADO连接,使用ADO对象执行SQL命令,以及如何在不同的场景下读取、插入、修改和删除数据库中的数据。通过实例代码演示了具体的实现过程,适用于初学者快速上手。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

[cpp] view plaincopy

1.    // 初始化COM,创建ADO连接等操作  

2.        if (!AfxOleInit()) {  

3.            AfxMessageBox("OLE/COM初始化失败");  

4.            return FALSE;  

5.    }  

6.        HRESULT hr;  

7.        try  

8.        {  

9.        //  hr = m_pConnection.CreateInstance("ADODB.Connection");///创建Connection对象  

10.          hr =    m_pConnection.CreateInstance(__uuidof(Connection));  

11.          if(SUCCEEDED(hr))  

12.          {  

13.              hr = m_pConnection->Open("Provider=Microsoft.Jet.OLEDB.4.0;Data Source=test1.mdb","","",adModeUnknown);///连接  

14.    

15.          //  hr = m_pConnection->Open("Provider=SQLOLEDB;server=(local);UID=sa;PWD=123;database=test1","","",adModeUnknown);  

16.    

17.          }  

18.      }  

19.      catch(_com_error e)///捕捉异常  

20.      {  

21.          CString errormessage;  

22.          errormessage.Format("连接数据库失败!\r错误信息:%s",e.ErrorMessage());  

23.          AfxMessageBox(errormessage);///显示错误信息  

24.      }  

 

 

一、点击”读取按钮“,从数据库中读取数据,在界面上显示,有三种方法:

[cpp] view plaincopy

1.    void CMyLinkMdbDlg::OnReadAccess()   

2.    {  

3.        // TODO: Add your control notification handler code here  

4.      /*******************以下提供了3种形式方法执行SQL命令*****************/  

5.      

6.        /*  ***********第一种  Execute 执行SQL命令**********    

7.     

8.        try 

9.        { 

10.      m_pRecordset.CreateInstance("ADODB.Recordset"); 

11.      _bstr_t strCmd="SELECT * FROM [user]"; 

12.      m_pRecordset=m_pConnection->Execute(strCmd,&RecordsAffected,adCmdText); 

13.      } 

14.      catch(_com_error *e) 

15.      { 

16.          AfxMessageBox(e->Description()); 

17.      } 

18.   */  

19.    

20.    

21.       /************第二种   command命令操作SQL语句************ 

22.          m_pCommand.CreateInstance("ADODB.Command"); 

23.          _variant_t vNULL; 

24.          vNULL.vt = VT_ERROR; 

25.          vNULL.scode = DISP_E_PARAMNOTFOUND;///定义为无参数 

26.          m_pCommand->ActiveConnection = m_pConnection;///非常关键的一句,将建立的连接赋值给它 

27.          m_pCommand->CommandText = "SELECT * FROM [user]";///命令字串 

28.          m_pRecordset = m_pCommand->Execute(&vNULL,&vNULL,adCmdText);///执行命令,取得记录集 

29.       */  

30.    

31.     /**************第三种   直接用open执行SQL语句 *************/  

32.      m_pRecordset.CreateInstance(__uuidof(Recordset));  

33.      try  

34.      {  

35.          m_pRecordset->CursorLocation   =   adUseClient;          //若需要排序的话必须要  

36.          m_pRecordset->Open("SELECT * FROM [user1]",                // 查询DemoTable表中所有字段  

37.              _variant_t((IDispatch *)m_pConnection,true),     // 获取库接库的IDispatch指针  

38.              adOpenDynamic,  

39.              adLockOptimistic,  

40.              adCmdText);  

41.          m_pRecordset->Sort   =   "id   asc";          //按照id升序排序  

42.    

43.      }  

44.      catch(_com_error *e)  

45.      {  

46.          AfxMessageBox(e->ErrorMessage());  

47.      }  

48.      

49.    

50.    

51.    

52.    

53.      _variant_t vID,vName,vAge;            

54.      // 清空列表框  

55.      m_DataList.ResetContent();  

56.      m_DataList.SetCurSel(0);  

57.      vName=vAge="";  

58.      // ADO操作中建议语句中要常用try...catch()来捕获错误信息,  

59.      // 因为它有时会经常出现一些想不到的错误。jingzhou xu  

60.    

61.      try  

62.      {  

63.          if(!m_pRecordset->BOF)  

64.              m_pRecordset->MoveFirst();  

65.          else  

66.          {  

67.              AfxMessageBox("表内数据为空");  

68.              return;  

69.          }  

70.              CString strtemp;  

71.              while (!m_pRecordset->adoEOF)  

72.              {  

73.                  strtemp = "";  

74.                  vID=m_pRecordset->GetCollect(_variant_t((long)0));  

75.                  //取得第1列的值,从0开始计数,你也可以直接列出列的名称,如下一行  

76.                  vName=m_pRecordset->GetCollect("name");  

77.                  vAge=m_pRecordset->GetCollect("age");  

78.                    

79.                

80.                  if(vID.vt != VT_NULL)  

81.                  {  

82.                      strtemp.Format("%d",vID.lVal);  

83.                  }  

84.                    

85.                  if(vName.vt != VT_NULL)  

86.                  {  

87.                      strtemp += "             ";  

88.                      strtemp += (LPCTSTR)(_bstr_t)vName;  

89.                  }  

90.                    

91.                  if(vAge.vt != VT_NULL)  

92.                  {  

93.                      strtemp += "             ";  

94.                      strtemp += (LPCTSTR)(_bstr_t)vAge;  

95.                  }             

96.                  m_DataList.AddString(strtemp);    

97.                  UpdateData(FALSE);        

98.                  m_pRecordset->MoveNext();  

99.              }  

100.              m_DataList.SetCurSel(0);  

101.              OnSelchangeData();  

102.            

103.      }  

104.      catch(_com_error *e)  

105.      {  

106.          AfxMessageBox(e->ErrorMessage());  

107.      }  

108.      m_pRecordset->Close();  

109.      m_pRecordset=NULL;  

110.    

111.  }  

 

二、插入数据

[cpp] view plaincopy

1.    void CMyLinkMdbDlg::OnInsert()   

2.    {  

3.        // TODO: Add your control notification handler code here  

4.        UpdateData(TRUE);  

5.        if (m_Age == "" || m_Name == "")  

6.        {  

7.            AfxMessageBox("输入不能为空");  

8.            return;  

9.        }  

10.    

11.      m_pRecordset.CreateInstance(__uuidof(Recordset));  

12.      try  

13.      {  

14.          m_pRecordset->Open("SELECT * FROM [user1]",                // 查询DemoTable表中所有字段  

15.              _variant_t((IDispatch *)m_pConnection,true),     // 获取库接库的IDispatch指针  

16.              adOpenDynamic,  

17.              adLockOptimistic,  

18.              adCmdText);  

19.          m_pRecordset->AddNew();                         //用这种方法添加数据就必须用open 语句执行SQL语句  

20.          m_pRecordset->PutCollect("name", _variant_t(m_Name));  

21.          m_pRecordset->PutCollect("age", atol(m_Age));  

22.          m_pRecordset->Update();  

23.          m_pRecordset->Close();  

24.          AfxMessageBox("插入成功!");  

25.          OnReadAccess();  

26.    

27.      }  

28.      catch(_com_error *e)  

29.      {  

30.          AfxMessageBox(e->ErrorMessage());  

31.      }  

32.    

33.      m_pRecordset=NULL;  

34.    

35.  }  


三、修改数据

[cpp] view plaincopy

1.    void CMyLinkMdbDlg::OnModify()   

2.    {  

3.        // TODO: Add your control notification handler code here  

4.        int cursel = m_DataList.GetCurSel();         //得到当前所选记录的索引  

5.      

6.        UpdateData(TRUE);  

7.        if (m_Age == "" || m_Name == "")  

8.        {  

9.            AfxMessageBox("输入不能为空");  

10.          return;  

11.      }  

12.      m_pRecordset.CreateInstance(__uuidof(Recordset));  

13.      try  

14.      {  

15.          m_pRecordset->Open("SELECT * FROM [user1]",                // 查询DemoTable表中所有字段  

16.              _variant_t((IDispatch *)m_pConnection,true),     // 获取库接库的IDispatch指针  

17.              adOpenDynamic,  

18.              adLockOptimistic,  

19.              adCmdText);  

20.          m_pRecordset->MoveFirst();  

21.          m_pRecordset->Move(cursel);  

22.          m_pRecordset->PutCollect("name", _variant_t(m_Name));  

23.          m_pRecordset->PutCollect("age", atol(m_Age));  

24.          m_pRecordset->Update();  

25.          m_pRecordset->Close();  

26.          OnReadAccess();                 //修改后需重新读取数据库  

27.    

28.          m_DataList.SetCurSel(cursel);       //修改后指针仍旧指向刚修改的记录  

29.            

30.      }  

31.      catch(_com_error *e)  

32.      {  

33.          AfxMessageBox(e->ErrorMessage());  

34.      }  

35.        

36.      m_pRecordset=NULL;  

37.  }  


四、删除数据

[cpp] view plaincopy

1.    void CMyLinkMdbDlg::OnDelete()   

2.    {  

3.        // TODO: Add your control notification handler code here  

4.        int cursel = m_DataList.GetCurSel();         //得到当前所选记录的索引  

5.          

6.        m_pRecordset.CreateInstance(__uuidof(Recordset));  

7.        try  

8.        {  

9.            m_pRecordset->Open("SELECT * FROM [user1]",                // 查询DemoTable表中所有字段  

10.              _variant_t((IDispatch *)m_pConnection,true),     // 获取库接库的IDispatch指针  

11.              adOpenDynamic,  

12.              adLockOptimistic,  

13.              adCmdText);  

14.          m_pRecordset->MoveFirst();  

15.          m_pRecordset->Move(cursel);  

16.          m_pRecordset->Delete(adAffectCurrent);             //参数adAffectCurrent为删除当前记录  

17.          m_pRecordset->Update();  

18.          m_pRecordset->Close();  

19.          OnReadAccess();                 //修改后需重新读取数据库  

20.            

21.          m_DataList.SetCurSel(cursel - 1);  

22.            

23.      }  

24.      catch(_com_error *e)  

25.      {  

26.          AfxMessageBox(e->ErrorMessage());  

27.      }  

28.        

29.      m_pRecordset=NULL;  

30.  }  

 

以上四部分完成了数据库最常用的增、删、改、查功能~

先在程序初始化函数中完成COM的初始化和数据库的连接,再在每一个增删改查的函数中,创建记录集

[cpp] view plaincopy

1.    m_pRecordset  

用m_pRecordset调用Open函数,打开数据库,获取数据记录集,

再用m_pRecordset就可以灵活调用数据库了~~

 

 

在读取数据库内容函数中:

(1)

if(!m_pRecordset->BOF)
m_pRecordset->MoveFirst();

还有

while (!m_pRecordset->adoEOF)

{

……

m_pRecordset->MoveNext();

……

}

 

这里就涉及到BOF和EOF的作用,其实上面的 if 和 while 的写法基本上就是固定的了,在不同的应用程序里都差不多~~

简单的说,

~使用 BOF 和 EOF(adoEOF) 属性可确定 Recordset 对象是否包含记录,或者从一个记录移动到另一个记录时是否超出 Recordset 对象的限制。
~如果当前记录位于第一个记录之前,BOF 属性将返回 True (-1),如果当前记录为第一个记录或位于其后则将返回 False (0)。 
~如果当前记录位于 Recordset 对象的最后一个记录之后 EOF(adoEOF)  属性将返回 True,而当前记录为 Recordset 对象的最后一个记录或位于其前,则将返回 False。
~如果 BOF EOF(adoEOF) 属性为 True,则没有当前记录

也即是说,if(!m_pRecordset->BOF)
m_pRecordset->MoveFirst();

这里的作用就是,如果表内数据不为空,就把记录集指针移动到第一条记录(MoveFirst),移动指针到记录集中的第一行)

现在就可以用m_pRecordset调用其他函数对数据库里的内容进行操作了~~

 

在while循环中,易看出,当我们读取记录集中的数据时,只要没有读到末尾,那么,一直调用m_pRecordset->MoveNext(); 让指针下移~~

 

(2)在”插入数据库“部分,有以下代码:

m_pRecordset->AddNew();                        //用这种方法添加数据就必须用open 语句执行SQL语句
m_pRecordset->PutCollect("name", _variant_t(m_Name));
m_pRecordset->PutCollect("age", atol(m_Age));
m_pRecordset->Update();
      m_pRecordset->Close();

AddNew 这个是让表添加一个新行

再执行下面两个Putcollect ,

put 放入的意思。这里是把m_Name值放入表中的name字段中;m_Age放入age 字段中~~

Update是更新数据记录集

Close是关闭数据记录集~

 

(3)修改数据部分,有下列代码:

                               m_pRecordset->MoveFirst();

                               m_pRecordset->Move(cursel);

                               m_pRecordset->PutCollect("name",_variant_t(m_Name));

                               m_pRecordset->PutCollect("age",atol(m_Age));

                               m_pRecordset->Update();

                               m_pRecordset->Close();

MoveFirst 移动指针到记录集的第一行(即,设置默认情况下,指针在第一行)

Move(cursel),移动到cursel行,即移动到光标指向的位置(光标的位置要响应ListBox的单击响应函数)

由于记录集指针在光标指向的位置,所以再执行下面两个PutCollect 函数时,再往该行中写入数据,相当于把原来该行的数据覆盖了~~就能起到修改的作用~~

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值