VC++中通过ADO中的_RecordsetPtr操作数据库:增删改查

_RecordsetPtr智能指针,它是专门为通过记录集操作数据库而设立的指针,通过该接口可以对数据库的表内的记录、字段等进行各种操作。

要搞清楚:数据库和ADO的记录集是两个不同的概念,是存在于不同物理位置的两个存储空间。记录集相当于是实际数据的一份拷贝。正因为记录集是相对脱离数据库而存在的,所以才存在后面将要介绍的Open方法中涉及的光标类型和锁定类型这两个问题。

_RecordsetPtr接口的使用方法:

先创建记录集对象:

_ConnectionPtr m_pRecordset;

m_pRecordset.CreateInstance(__uuidof(Recorset));

创建记录集对象后,只是为它分配内存空间,记录集中不含任何数据。记录集对象是用来获得数据库中的数据并对其操作的,所以还要打开记录集,从数据库中取得数据记录。可有多种方法打开记录集,下面只介绍最常用的Open方法:

为记录集对象分配了空间后就可以用Open函数打开记录集,该函数原型为:

HRESULT Recordset15::Open(const_variant_t& Source,const_variant_t& ActiveConnection,enum CursorTypeEnumCursorType,enum LockTypeEnum LockType,long Options)

参数:

Source是数据查询字符串。

ActiveConnection是已经建立好的连接(我们需要用Connection对象指针来构造一个_variant_t对象)。

CursorType 光标类型,它是枚举CursorTypeEnum中的一个值。

LockType 锁定类型 它是枚举LockTypeEnum中的一个值

Options 指定Source的类型

光标类型CursorType,可取如下值之一:

adOpenUnspecified=-1 不作特别指定

adOpenForwardOnly=0默认值,前滚静态光标。这种光标只能向前浏览记录集,比如用MoveNext向前滚动,这种方式可节省资源,提高浏览速度,但诸如BookMark、RecordCount、AbsolutePosition、AbsolutePage都不能使用。

adOpenKeyset=1键集游标,采用这种光标的记录集看不到其它用户的新增、删除操作,但对于更新原有记录的操作对你是可见的。

adOpenDynamic=2动态光标,所有数据库的操作都会立即在用户记录集上反应出来。

adOpenStatic=3静态游标。它为记录产生一个静态备份,其他用户的新增、删除、更新操作对你的记录集来说是不可见的。

LockType锁定类型,它可以是以下值之一,请看如下枚举结构

enum LockTypeEnum

{

   adLockUnspecified=-1,

   //未指定

   adLockReadOnly=1,

   //只读记录集,默认值。无法更改数据。

   adLockPessimistic=2,

   //悲观锁定方式。只有在调用Update方法时才锁定记录。这是最安全的锁定机制

   adLockOptimistc=3,

   //乐观锁定方式,只有在你调用Update方法时才锁定记录。

   在此之前仍然可以做数据的更新、插入、删除等操作

adLockBatchOptimistic=4乐观分批更新。编辑时记录不会锁定,更改、插入及删除是在批处理模式下完成。

}

关于光标和锁定类型,对于一般用户,建议您只作简单了解,后面将进一步进行解说。

Options可以取如下值之一:

adCmdText: 表明CommandText是文本命令。

adCmdTable:表明CommandText是一个表名。

adCmdProc:表明CommandText是一个存储过程。

adCmdUnknown:未知。

例如:假设m_pConnection是我们已经建立好的连接,我们使用_RecordsetPtr接口的Open方法打开Employees表的记录集的语句如下:

m_pRecordset->Open(“SELECT * FROMEmployees”,

          _variant_t((IDispatch*)m_pConnection,true),

          adOpenStatic,

          adLockOptimistic,

          adCmdText);

例程RecordsetPtr演示使用_RecordsetPtr指针通过记录集操作数据库。

打开VC++6.0,新建一个基于对话框的工程RecordsetPtr。在对话框IDD_RECORDSETPTR_DIALOG中进行编辑:

使用三个GroupBox分成四个部分,第一部分演示如何读取数据库数据;第二部分演示如何修改数据库;第三部分演示如何向数据库中插入数据;第四部分演示如何删除数据库中的数据。

使用ClassWizard给列表框IDC_LIST1创建CListBox变量m_list1:

双击IDC_BTN_READREC按钮,并编辑OnBtnReadrec()函数如下:

void CRecordsetPtrDlg::OnBtnReadrec()

{

   _ConnectionPtr m_pConnection;

   

   _RecordsetPtr m_pRecordset;

   try

   {

      m_pConnection.CreateInstance(__uuidof(Connection));

      m_pConnection->Open("Provider=Microsoft.Jet.OLEDB.4.0;DataSource=Northwind.mdb","","",adModeUnknown);

   }

   catch(_com_error e)

   {

      CString errormessage;

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

      AfxMessageBox(errormessage);

      return;

   }

   try

   {

      m_pRecordset.CreateInstance("ADODB.Recordset");

      m_pRecordset->Open("SELECTEmployeeID,FirstName,LastName,HireDate,City FROM Employees WHERECity='London'",

          _variant_t((IDispatch*)m_pConnection,true),

          adOpenStatic,

          adLockOptimistic,

          adCmdText);

   }

   catch(_com_error &e)

   {

      AfxMessageBox(e.Description());

   }

   _variant_tvEmployeeID,vFirstName,vLastName,vHireDate,vCity;

   try

   {

      while(!m_pRecordset->adoEOF)

      {

          vEmployeeID=m_pRecordset->GetCollect(_variant_t((long)0));

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

          vFirstName=m_pRecordset->GetCollect("FirstName");

          vLastName=m_pRecordset->GetCollect("LastName");

          vHireDate=m_pRecordset->GetCollect("HireDate");

          vCity=m_pRecordset->GetCollect("City");

          CString strtemp;

          if(vEmployeeID.vt!=VT_NULL)

          {

             strtemp.Format("%d",vEmployeeID.lVal);

          }

          if(vFirstName.vt!=VT_NULL)

          {

             strtemp+="     ";

             strtemp+=(LPCTSTR)(_bstr_t)vFirstName;

          }

          if(vLastName.vt!=VT_NULL)

          {

             strtemp+="     ";

             strtemp+=(LPCTSTR)(_bstr_t)vLastName;

          }

          if(vHireDate.vt!=VT_NULL)

          {

             strtemp+="     ";

             strtemp+=(LPCTSTR)(_bstr_t)vHireDate;

          }

          if(vCity.vt!=VT_NULL)

          {

             strtemp+="     ";

             strtemp+=(LPCTSTR)(_bstr_t)vCity;

          }

          m_list1.AddString(strtemp);

          

          m_list1.AddString("\n");

          m_pRecordset->MoveNext();

      }

      

   }

   catch(_com_error &e)

   {

      AfxMessageBox(e.Description());

   }

   m_pRecordset->Close();

   m_pRecordset=NULL;

   m_pConnection->Close(); 

   m_pConnection=NULL; 

}

该段代码演示了如何读取数据库表内的数据。其原理是如果没有遇到表结束标志adoEOF,则用GetCollect(字段名)来获取当前记录指针所指的字段值,然后再用MoveNext()方法移动到下一条记录位置。

双击IDC_BTN_CHANGE按钮,并编辑OnBtnChange()函数如下:

void CRecordsetPtrDlg::OnBtnChange()

{

   _ConnectionPtr m_pConnection;

   

   _RecordsetPtr m_pRecordset;

   try

   {

      m_pConnection.CreateInstance(__uuidof(Connection));

      m_pConnection->Open("Provider=Microsoft.Jet.OLEDB.4.0;DataSource=Northwind.mdb","","",adModeUnknown);

   }

   catch(_com_error e)

   {

      CString errormessage;

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

      AfxMessageBox(errormessage);

      return;

   }

   try

   {

      m_pRecordset.CreateInstance("ADODB.Recordset");

      m_pRecordset->Open("SELECTEmployeeID,FirstName,LastName,HireDate,City FROM Employees WHERE(City='London') AND (EmployeeID=6)",

          _variant_t((IDispatch*)m_pConnection,true),

          adOpenStatic,

          adLockOptimistic,

          adCmdText);

   }

   catch(_com_error &e)

   {

      AfxMessageBox(e.Description());

   }

   try

   {

      while(!m_pRecordset->adoEOF)

      {

          m_pRecordset->PutCollect("LastName",_variant_t("Jackson"));

          m_pRecordset->MoveNext();

      }

      m_pRecordset->Update();

   }

   catch(_com_error* e)

   {

      AfxMessageBox(e->ErrorMessage());

   }

   

   m_pRecordset->Close();

   m_pRecordset=NULL;

   m_pConnection->Close(); 

   m_pConnection=NULL;

}

该段代码演示了如何修改记录中的字段值:

将记录指针移动到要修改记录的位置处,直接用PutCollect(字段名,值)将新值写入并Update()更新到数据库即可。

移动记录指针可以通过MoveFirst()方法移动到第一条记录,MoveLast()方法移动到最后一条记录,MovePrevious()方法移动到当前记录的前一条记录,MoveNext()方法移动到当前记录的下一条记录。也可以使用Move(记录号)移动记录指针到需要位置。注意:Move()方法是相对于当前记录来移动指针位置的。正值向后移动,负值向前移动。如Move(3),当前记录是3时,它将从记录3开始往后再移动3条记录位置。关于移动记录指针后面将会用到。

双击IDC_BTN_NEW按钮,并编辑OnBtnNew()函数如下:

void CRecordsetPtrDlg::OnBtnNew()

{

   _ConnectionPtr m_pConnection;

   

   _RecordsetPtr m_pRecordset;

   try

   {

      m_pConnection.CreateInstance(__uuidof(Connection));

      m_pConnection->Open("Provider=Microsoft.Jet.OLEDB.4.0;DataSource=Northwind.mdb","","",adModeUnknown);

   }

   catch(_com_error e)

   {

      CString errormessage;

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

      AfxMessageBox(errormessage);

      return;

   }

   try

   {

      m_pRecordset.CreateInstance("ADODB.Recordset");

      m_pRecordset->Open("SELECT * FROMEmployees",

          _variant_t((IDispatch*)m_pConnection,true),

          adOpenStatic,

          adLockOptimistic,

          adCmdText);

   }

   catch(_com_error &e)

   {

      AfxMessageBox(e.Description());

   }

   try

   {

      m_pRecordset->MoveLast();

      m_pRecordset->AddNew();

      m_pRecordset->PutCollect("EmployeeID",_variant_t((long)10));

      m_pRecordset->PutCollect("FirstName",_variant_t("Mary"));

      m_pRecordset->PutCollect("LastName",_variant_t("Williams"));

      m_pRecordset->PutCollect("HireDate",_variant_t("15/4/199312:00:00"));

      m_pRecordset->PutCollect("City",_variant_t("NewYork"));

      m_pRecordset->PutCollect("Country",_variant_t("USA"));

   }

   

   catch(_com_error *e)

   {

      AfxMessageBox(e->ErrorMessage());

   }

   

   m_pRecordset->Update();

   m_pRecordset->Close();

   m_pRecordset=NULL;

   m_pConnection->Close(); 

   m_pConnection=NULL;

}

该段代码演示如何插入记录:

先用AddNew()方法新增一个空记录,再用PutCollect(字段名,值)输入每个字段的值,最后用Update()更新到数据库即可。

双击IDC_BTN_DELETE按钮,并编辑OnBtnDelete()函数如下:

void CRecordsetPtrDlg::OnBtnDelete()

{

   _ConnectionPtr m_pConnection;

   

   _RecordsetPtr m_pRecordset;

   try

   {

      m_pConnection.CreateInstance(__uuidof(Connection));

      m_pConnection->Open("Provider=Microsoft.Jet.OLEDB.4.0;DataSource=Northwind.mdb","","",adModeUnknown);

   }

   catch(_com_error e)

   {

      CString errormessage;

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

      AfxMessageBox(errormessage);

      return;

   }

   try

   {

      m_pRecordset.CreateInstance("ADODB.Recordset");

      m_pRecordset->Open("SELECT * FROMEmployees",

          _variant_t((IDispatch*)m_pConnection,true),

          adOpenStatic,

          adLockOptimistic,

          adCmdText);

   }

   catch(_com_error &e)

   {

      AfxMessageBox(e.Description());

   }

   try

   {

      //假设删除第10条记录

      m_pRecordset->MoveFirst();

      m_pRecordset->Move(9);

      m_pRecordset->Delete(adAffectCurrent);

      //参数adAffectCurrent为删除当前记录

      m_pRecordset->Update();

   }

   catch(_com_error *e)

   {

      AfxMessageBox(e->ErrorMessage());

   }

   m_pRecordset->Close();

   m_pRecordset=NULL;

   m_pConnection->Close(); 

   m_pConnection=NULL; 

}

该段代码演示了如何删除记录:

先将记录指针移动到要删除的记录的位置,直接用Delete()方法删除它,并用Update()来更新数据库即可。

使用记录集操作完毕后要关闭记录集:

直接用Close()方法关闭记录集并赋予其空值。代码如下:

m_pRecordset->Close();

m_pConnection->Close();

m_pRecordset=NULL;

m_pConnection=NULL;


  • 5
    点赞
  • 40
    收藏
    觉得还不错? 一键收藏
  • 3
    评论
以下是一个简单的C++ ADO封装连接sqlserver数据库的示例代码,包含连接、增删查改等功能: 头文件: ```c++ #pragma once #include <iostream> #include <windows.h> #import "C:\Program Files\Common Files\System\ado\msado15.dll" no_namespace rename("EOF", "adoEOF") class CADOConn { public: CADOConn(); ~CADOConn(); bool Open(const std::wstring& strConn); void Close(); bool ExecuteSQL(const std::wstring& strSQL); bool ExecuteSQL(const std::wstring& strSQL, _RecordsetPtr& pRs); bool Add(const std::wstring& strSQL); bool Delete(const std::wstring& strSQL); bool Update(const std::wstring& strSQL); bool Select(const std::wstring& strSQL, _RecordsetPtr& pRs); private: _ConnectionPtr m_pConn; }; ``` 源文件: ```c++ #include "ADOConn.h" CADOConn::CADOConn() : m_pConn(nullptr) { CoInitialize(nullptr); } CADOConn::~CADOConn() { Close(); CoUninitialize(); } bool CADOConn::Open(const std::wstring& strConn) { try { if (m_pConn != nullptr) { Close(); } HRESULT hr = m_pConn.CreateInstance(__uuidof(Connection)); if (FAILED(hr)) { throw _com_error(hr); } hr = m_pConn->Open(strConn.c_str(), L"", L"", adModeUnknown); if (FAILED(hr)) { throw _com_error(hr); } } catch (_com_error e) { std::cerr << "Error: " << e.Description() << std::endl; return false; } return true; } void CADOConn::Close() { if (m_pConn != nullptr) { m_pConn->Close(); m_pConn.Release(); } } bool CADOConn::ExecuteSQL(const std::wstring& strSQL) { try { if (m_pConn == nullptr) { return false; } HRESULT hr = m_pConn->Execute(strSQL.c_str(), nullptr, adCmdText); if (FAILED(hr)) { throw _com_error(hr); } } catch (_com_error e) { std::cerr << "Error: " << e.Description() << std::endl; return false; } return true; } bool CADOConn::ExecuteSQL(const std::wstring& strSQL, _RecordsetPtr& pRs) { try { if (m_pConn == nullptr) { return false; } pRs.CreateInstance(__uuidof(Recordset)); HRESULT hr = pRs->Open(strSQL.c_str(), m_pConn.GetInterfacePtr(), adOpenStatic, adLockReadOnly, adCmdText); if (FAILED(hr)) { throw _com_error(hr); } } catch (_com_error e) { std::cerr << "Error: " << e.Description() << std::endl; return false; } return true; } bool CADOConn::Add(const std::wstring& strSQL) { return ExecuteSQL(strSQL); } bool CADOConn::Delete(const std::wstring& strSQL) { return ExecuteSQL(strSQL); } bool CADOConn::Update(const std::wstring& strSQL) { return ExecuteSQL(strSQL); } bool CADOConn::Select(const std::wstring& strSQL, _RecordsetPtr& pRs) { return ExecuteSQL(strSQL, pRs); } ``` 主函数调用: ```c++ int main() { // 建立连接 CADOConn conn; std::wstring strConn = L"Provider=SQLOLEDB;Data Source=localhost;Initial Catalog=MyDB;User Id=sa;Password=123456;"; if (!conn.Open(strConn)) { std::cerr << "Failed to connect to database!" << std::endl; return -1; } // 插入数据 std::wstring strSQL = L"INSERT INTO MyTable (ID, Name) VALUES (1, 'Tom')"; if (!conn.Add(strSQL)) { std::cerr << "Failed to insert data!" << std::endl; } // 查询数据 strSQL = L"SELECT * FROM MyTable"; _RecordsetPtr pRs; if (conn.Select(strSQL, pRs)) { while (!pRs->adoEOF) { std::wcout << pRs->Fields->GetItem(L"ID")->Value.intVal << L"\t" << pRs->Fields->GetItem(L"Name")->Value.bstrVal << std::endl; pRs->MoveNext(); } } else { std::cerr << "Failed to select data!" << std::endl; } // 更新数据 strSQL = L"UPDATE MyTable SET Name='Jerry' WHERE ID=1"; if (!conn.Update(strSQL)) { std::cerr << "Failed to update data!" << std::endl; } // 删除数据 strSQL = L"DELETE FROM MyTable WHERE ID=1"; if (!conn.Delete(strSQL)) { std::cerr << "Failed to delete data!" << std::endl; } // 关闭连接 conn.Close(); return 0; } ``` 以上是一个简单的C++ ADO封装连接sqlserver数据库的示例代码,可以实现基本的增删查改等功能,具体的SQL语句需要根据实际情况进行调整。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值