MFC中使用ADO进行数据库操作


转:https://www.cnblogs.com/sunniflyer/p/4118956.html

数据库与数据库编程:

  • 当前各种主流数据库有很多,包括Oracle, MS SQL Server, Sybase, Informix, MySQL, DB2, Interbase / Firebird, PostgreSQL, SQLite, SAP/DB, TimesTen, MS ACCESS等等。
  • 数据库编程是对数据库的创建、读写等一列的操作。数据库编程分为数据库客户端编程数据库服务器端编程。数据库客户端编程主要使用ODBC API、ADO、ADO.NET、OCI、OTL等方法;数据库服务端编程主要使用OLE DB等方法。
  • 数据库编程需要掌握一些访问数据库技术方法,还需要注意怎么设计高效的数据库、数据库管理与运行的优化、数据库语句的优化。

ADO编程的一般步骤:

  1.   创建一个Connection对象  
  2.   打开数据源,建立同数据源的连接  
  3.   执行一个SQL命令 
  4.   使用结果集
  5.   终止连接

ADO最重要的三个对象:

  1. 连接对象(Connection)
  2. 命令对象(Command)
  3. 记录集对象(RecordSet)

在使用这三个对象的时候,需要定义与之相对应的智能指针:_ConnectionPtr、_CommandPtr、_RecordsetPtr

使用智能指针要:定义指针变量、创建其实例(实例化)、调用方法和属性。该智能指针在析构对象时,自动调用Release方法,即使用后不需要手动释放内存,代码更加简洁。

但需要调用Close方法,关闭连接Connection或者记录集RecordSet。

一、ADO编程预处理操作

1.1 导入ADO动态链接库:

在工程的stdafx.h中加入如下语句:

#import "c:\\Program Files\\Common Files\\System\\ADO\\msado15.dll" rename_namespace("ADOCG") rename("EOF","adoEOF") //rename("BOF","adoBOF") no_namespace
using namespace ADOCG;

注:import代码要在一行中完成,换行需添加'\'

1.2 初始化OLE/COM库环境:

在基于MFC的应用里,在应用类的InitInstance成员函数中初始化OLE/COM库环境,直接使用AfxOleInit,在退出应用时,该函数自动负责COM资源的释放,比较方便,不用在

ExitInitInstance中添加相关操作:

http://baike.baidu.com/view/2798823.htm?fr=aladdin com编程: http://baike.baidu.com/view/6923408.htm?fr=aladdin

四、实例演示

 4.1 初始化引入相关的库+Connection对象的创建和数据库的连接

william_w_l 2018-08-24 12:25:06  5000 https://www.cnblogs.com/sunniflyer/p/4118956.html

http://baike.baidu.com/view/2798823.htm?fr=aladdin

com编程: http://baike.baidu.com/view/6923408.htm?fr=aladdin

四、实例演示

 4.1 初始化引入相关的库+Connection对象的创建和数据库的连接

 

  1.   #import "c:\\Program Files\\Common Files\\System\\ADO\\msado15.dll" rename_namespace("ADOCG") rename("EOF","adoEOF") //rename("BOF","adoBOF")
  2.   using namespace ADOCG;
  3.   //... ...
  4.   _ConnectionPtr m_pConnection;
  5.   //... ...
  6.   if(!AfxOleInit())
  7.   {
  8.   AfxMessageBox("初始化OLE DLL失败!");
  9.   Return FALSE;
  10.   }
  11.    
  12.   m_pConnection.CreateInstance("ADODB.Connection");
  13.   try
  14.   {
  15.   m_pConnection->ConnectionTimeout = 3;
  16.   //连接ACCESS2000
  17.   m_pConnection->Open("Provider=Microsoft.Jet.OLEDB.4.0;Data Source=d:/Attendence/AttendenceDB.mdb","","",adModeUnknown);
  18.   }
  19.   catch(_com_error e)
  20.   {
  21.   AfxMessageBox(e.Description() + _T("\n数据库连接失败"));
  22.   }

 

 4.2 Recordset对象的声明与创建实例:

  1.   _RecordsetPtr m_pRecordset;
  2.   m_pRecordset.CreateInstance(__uuidof(Recordset)); //创建实例

 4.3 读取记录内容:

 

  1.   CString sqlHasRecord;
  2.   sqlHasRecord.Format("SELECT * FROM WorkUser WHERE MemberID = '%s'" , m_StringNumber);
  3.   HRESULT hr = m_pRecordset->Open(sqlHasRecord.GetBuffer(0), _variant_t((IDispatch*)theApp.m_pConnection, true), adOpenDynamic, adLockPessimistic, adCmdText);
  4.    
  5.   if (SUCCEEDED(hr))
  6.   {
  7.   while (!m_pRecordset->adoEOF || !m_pRecordset->BOF)//遍历返回的每一条记录
  8.   {
  9.   CString m_StringID;
  10.   m_StringID = (LPCSTR)_bstr_t(m_pRecordset->GetCollect("FeatureID"));//读取id
  11.        m_pRecordset->MoveNext();
  12.   }
  13.   }
  14.   m_pRecordset->Close();
  15.   //记录用完之后需要关闭

 

 4.4 插入新记录:

 

  1.   CString strSql;
  2.   strSql.Format("INSERT INTO WorkUser(MemberName, MemberID, MemberPosition, FeatureID, BeDeleted, SendedToClient) VALUES('%s', '%s', '%s', %d, 0, 0)",“ZhangSan”,”14S051000”, “Student”, 16);
  3.   try
  4.   {
  5.    
  6.   (theApp.m_pConnection)->Execute(_bstr_t(strSql), 0, adCmdText);
  7.   }
  8.   catch(_com_error e)
  9.   {
  10.   MessageBox(e.Description());
  11.   return;
  12.   }

 

 4.5 更新记录:

 

  1.   strSql.Format(_T("UPDATE WorkUser SET MemberName = '%s', MemberPosition = '%s' WHERE MemberID = '%s' "),m_StringName, m_StringPosition, m_StringNumber);
  2.   try
  3.   {
  4.    
  5.   (theApp.m_pConnection)->Execute(_bstr_t(strSql), 0, adCmdText);
  6.   }
  7.   catch(_com_error e)
  8.   {
  9.   MessageBox(e.Description());
  10.   return;
  11.   }

 

 4.6 删除记录:

 

  1.   CString strSql;
  2.   strSql.Format(_T("DELETE FROM WorkUser WHERE FeatureID = %s "), FeatureID[i]);
  3.   try
  4.   {
  5.   (theApp.m_pConnection)->Execute(_bstr_t(strSql), 0, adCmdText);
  6.   }
  7.   catch(_com_error e)
  8.   {
  9.   MessageBox(e.Description());
  10.   return FALSE;
  11.   }

 

4.7 读取字节流文件:

读取图像数据:

 

  1.   try
  2.   {
  3.   CString sql;
  4.   sql.Format("select * from WorkUser where MemberID='%s'",MemberID);
  5.    
  6.   HRESULT hr = m_pRecordset->Open(sql.GetBuffer(0),_variant_t((IDispatch *)theApp.m_pConnection,true),adOpenDynamic,adLockPessimistic,adCmdText);
  7.   if(SUCCEEDED(hr))
  8.   {
  9.   if(m_pRecordset->adoEOF||m_pRecordset->BOF)
  10.   {
  11.    
  12.   MessageBox(_T("数据库中没有相应的记录"));
  13.   return;
  14.   }
  15.   else
  16.   {
  17.   long lDataSize = m_pRecordset->GetFields()->GetItem(imgColName.GetBuffer(0))->ActualSize;
  18.   if (lDataSize>0)
  19.   {
  20.   _variant_t varBLOB;
  21.   varBLOB = m_pRecordset->GetFields()->GetItem(imgColName.GetBuffer(0))->GetChunk(lDataSize);
  22.   if(varBLOB.vt == (VT_ARRAY | VT_UI1))
  23.   {
  24.   if(buffer)               ///重新分配必要的存储空间
  25.   {
  26.   char *pBuf = NULL;
  27.   SafeArrayAccessData(varBLOB.parray,(void **)&pBuf);
  28.   memcpy(buffer,pBuf,lDataSize); ///复制数据到缓冲区buffer
  29.   SafeArrayUnaccessData (varBLOB.parray);
  30.    
  31.   }
  32.   }
  33.   }
  34.   else
  35.   {
  36.   MessageBox(_T("数据库中的图像数据为空!"));
  37.   return;
  38.   }
  39.   }
  40.   }
  41.   }
  42.   catch (...)
  43.   {
  44.   MessageBox(_T("数据库访问出错"));
  45.   }
  46.   m_pRecordset->Close();

4.8 保存字节流文件:

  1.   CString sql;
  2.   sql.Format("select * from WorkUser where MemberID='%s'",MemberID);
  3.   HRESULT hr = m_pRecordset->Open(sql.GetBuffer(0),_variant_t((IDispatch *)theApp.m_pConnection,true),adOpenDynamic,adLockPessimistic,adCmdText);
  4.    
  5.   if(SUCCEEDED(hr))
  6.   {
  7.   if (!m_pRecordset->adoEOF||!m_pRecordset->BOF)
  8.   {
  9.    
  10.    
  11.   char *pBuf = buffer;
  12.   VARIANT varBLOB;
  13.   SAFEARRAY *psa;
  14.   SAFEARRAYBOUND rgsabound[1];
  15.   if(pBuf)
  16.   {
  17.   rgsabound[0].lLbound = 0;
  18.   rgsabound[0].cElements = bufLength;
  19.   psa = SafeArrayCreate(VT_UI1, 1, rgsabound); //分配的数据类型为unsigned int (1 byte 长度的类型)
  20.   for (long i = 0; i < (long)bufLength; i++)
  21.   SafeArrayPutElement (psa, &i, pBuf++);
  22.    
  23.   varBLOB.vt = VT_ARRAY | VT_UI1;
  24.   varBLOB.parray = psa;
  25.   m_pRecordset->GetFields()->GetItem(imgColName.GetBuffer(0))->AppendChunk(varBLOB);
  26.   }
  27.   m_pRecordset->Update();
  28.   }
  29.   else
  30.   {
  31.   MessageBox(_T("数据库中没有相应用户的记录!"));
  32.   return;
  33.   }
  34.    
  35.   }
  36.   m_pRecordset->Close();
 
VC