在Visual C++中用ADO进行数据库编程_.docx

上传人:scccc 文档编号:11326234 上传时间:2021-07-23 格式:DOCX 页数:18 大小:18.83KB
返回 下载 相关 举报
在Visual C++中用ADO进行数据库编程_.docx_第1页
第1页 / 共18页
在Visual C++中用ADO进行数据库编程_.docx_第2页
第2页 / 共18页
在Visual C++中用ADO进行数据库编程_.docx_第3页
第3页 / 共18页
在Visual C++中用ADO进行数据库编程_.docx_第4页
第4页 / 共18页
在Visual C++中用ADO进行数据库编程_.docx_第5页
第5页 / 共18页
亲,该文档总共18页,到这儿已超出免费预览范围,如果喜欢就下载吧!
资源描述

《在Visual C++中用ADO进行数据库编程_.docx》由会员分享,可在线阅读,更多相关《在Visual C++中用ADO进行数据库编程_.docx(18页珍藏版)》请在三一文库上搜索。

1、在Visual C+中用ADO进行数据库编程_ 1.生成应用程序框架并初始化OLE/COM库环境 创建一个标准的MFC AppWizard(exe)应用程序,然后在用法ADO数据库的InitInstance函数中初始化OLE/COM库(由于ADO库是一个COM DLL库)。 本例为: BOOL CAdotestDlg:OnInitDialog() :CoInitialize(NULL); /初始化OLE/COM库环境 程序最终要调用 :CoUninitialize();/释放程序占用的COM 资源。 另外: m_pRecordset-Close(); 留意!不要多次关闭! m_pConnect

2、ion-Close(); m_pRecordset = NULL; m_pConnection = NULL; 2.引入ADO库文件 用法ADO前必需在工程的stdafx.h文件最终用挺直引入符号#import引入ADO库文件,以使编译器能正确编译。代码如下: #import “C:Program Filescommon filessystemadomsado15.dll” no_namespace rename(“EOF”,“adoEOF”) ADO类的定义是作为一种资源存储在ADO DLL(msado15.dll)中,在其内部称为类型库。类型库描述了自治接口,以及C+用法的COM vtab

3、le接口。当用法#import指令时,在运行时Visual C+需要从ADO DLL中读取这个类型库,并以此创建一组C+头文件。这些头文件具有。tli和。tlh扩展名,读者可以在项目的名目下找到这两个文件。在C+程序代码中调用的ADO类要在这些文件中定义。 程序的第三行指示ADO对象不用法名称空间。在有些应用程序中,由于应用程序中的对象与ADO中的对象之间可能会消失命名冲突,所以有必要用法名称空 间。假如要用法名称空间,则可把第三行程序修改为:rename_namespace(“AdoNS”)。第四行代码将ADO中的EOF(文件结束)更名 为adoEOF,以避开与定义了自己的EOF的其他库冲突

4、。 3.利用智能指针进行数据库操作 在CaboutDlg头文件中定义两个ADO智能指针类实例,并在对话框中加入一个ListCtrl. class CAdotestDlg : public CDialog _ConnectionPtrm_pConnection; _RecordsetPtrm_pRecordset; ClistCtrlm_List; ADO库包含三个智能指针:_ConnectionPtr、_CommandPtr和_RecordsetPtr. _ConnectionPtr通常被用来创建一个数据连接或执行一条不返回任何结果的SQL语句,如一个存储过程。 _CommandPtr返回一个

5、记录集。它供应了一种简洁的方法来执行返回记录集的存储过程和SQL语句。在用法_CommandPtr接口时,可以利 用全局_ConnectionPtr接口,也可以在_CommandPtr接口里挺直用法连接串。 _RecordsetPtr是一个记录集对象。与以上两种对象相比,它对记录集供应了更多的掌握功能,如记录锁定、游标掌握等。 在用法ADO程序的大事响应中OnButton1加入以下代码: void CAdotestDlg:OnButton1() m_List.ResetContent(); m_pConnection.CreateInstance(_uuidof(Connection); /初

6、始化Connection指针 m_pRecordset.CreateInstance(_uuidof(Recordset);/初始化Recordset指针 try m_pConnection-Open(“DSN=ADOTest”,“”,“”,0); /连接叫作ADOTest的ODBC数据源 /留意:这是连接不需要用户ID或密码的open 函数 / 否则形式为 -Open(“DSN=test;uid=sa;pwd=123;”,“”,“”,0); / 执行SQL语句得到一个记录集把其指针赋值给m_pRecordset CStringstrSql=“select * from middle”; BS

7、TR bstrSQL = strSql.AllocSysString(); m_pRecordset-Open(bstrSQL,(IDispatch*)m_pConnection,adOpenDynamic,adLockOptimistic, adCmdText); /adOpenDynamic:动态 adLockOptimistic乐观封锁法 adCmdText:文本查询语句 while(!m_pRecordset-adoEOF)/遍历全部记录 /取纪录字段值方式之一 _variant_tTheValue; /VARIANT数据类型 TheValue = m_pRecordset-GetCo

8、llect(“BIG_NAME”);/得到字段BIG_NAME的值 if(TheValue.vt!=VT_NULL) m_List.AddString(char*)_bstr_t(TheValue); /将该值加入到列表控件中 /取纪录字段值方式之二 / _bstr_t TheValue1=m_pRecordset-Fields-GetItem(“BIG_NAME”)-Value; / CString temp=TheValue1.copy(); / m_List.AddString(temp); /数据类型转换 _variant_tvUsername,vBirthday,vID,vOld;

9、TRACE(“id:%d,姓名:%s,年龄:%d,生日:%s “, vID.lVal,(LPCTSTR)(_bstr_t)vUsername,vOld.lVal,(LPCTSTR)(_bstr_t)vBirthday); m_pRecordset-MoveNext();/转到下一条纪录 m_pRecordset-Close(); m_pConnection-Close(); catch (_com_error e)/特别处理 AfxMessageBox(e.ErrorMessage(); m_pRecordset-Close(); /留意!不要多次关闭!否则会出错 m_pConnection-

10、Close(); m_pRecordset = NULL; m_pConnection = NULL; 程序中通过_variant_t和_bstr_t转换COM对象和C+类型的数据, _variant_t类封装了OLE自治VARIANT数据类型。在C+中用法_variant_t类要比挺直用法VARIANT数据类型简单得多。 好,编译后该程序就能运行了,但记住运行前要创建一个叫ADOTest的ODBC数据源。该程序将把表middle中的BIG_NAME字段值显示在列表控件中。 4.执行SQL指令并取得结果记录集 为了取得结果记录集,我们定义一个指向Recordset对象的指针:_Recordse

11、tPtrm_pRecordset; 并为其创建Recordset对象的实例: m_pRecordset.CreateInstance(”ADODB.Recordset“); SQL指令的执行可以采纳多种形式,下面我们一进行阐述。 (1)利用Connection对象的Execute方法执行SQL指令 Execute方法的原型如下所示: _RecordsetPtr Connection15:Execute ( _bstr_tCommandText, VARIANT * RecordsAffected, long Options ) 其中CommandText是指令字串,通常是SQL指令。 参数Re

12、cordsAffected是操作完成后所影响的行数, 参数Options表示CommandText中内容的类型,Options可以取如下值之一: adCmdText:表明CommandText是文本指令 adCmdTable:表明CommandText是一个表名 adCmdProc:表明CommandText是一个存储过程 adCmdUnknown:未知 Execute执行完后返回一个指向记录集的指针,下面我们给出具体代码并作说明。 _variant_tRecordsAffected; /执行SQL指令:CREATE TABLE创建表格users,users包含四个字段:整形ID,字符串use

13、rname, 整形old,日期型birthday m_pConnection-Execute(”CREATE TABLE users(ID INTEGER,usernameTEXT,oldINTEGER,birthday DATETIME)“, RecordsAffected, adCmdText); /往表格里面添加记录 m_pConnection-Execute(”INSERT INTO users(ID,username,old,birthday) VALUES (1, Washington,25,1970/1/1)“,RecordsAffected,adCmdText); /将全部记录

14、old字段的值加一 m_pConnection-Execute(”UPDATE users SET old = old+1“,RecordsAffected,adCmdText); /执行SQL统计指令得到包含记录条数的记录集 m_pRecordset = m_pConnection-Execute(”SELECT COUNT(*) FROM users“,RecordsAffected,adCmdText); _variant_tvIndex = (long)0; _variant_tvCount = m_pRecordset-GetCollect(vIndex);/取得第一个字段的值放入v

15、Count变量 上两句可以写成- _variant_tvCount = m_pRecordset-GetCollect(_variant_t)(long)0); m_pRecordset-Close();/关闭记录集 CString message; message.Format(”共有%d条记录“,vCount.lVal); AfxMessageBox(message);/显示当前记录条数 (2)利用Command对象来执行SQL指令 _CommandPtrm_pCommand; m_pCommand.CreateInstance(”ADODB.Command“); _variant_tvN

16、ULL; vNULL.vt = VT_ERROR; vNULL.scode = DISP_E_PARAMNOTFOUND;/定义为无参数 m_pCommand-ActiveConnection = m_pConnection;/特别关键的一句,将建立的连接赋值给它 m_pCommand-CommandText = “SELECT * FROM users”;/指令字串 m_pRecordset = m_pCommand-Execute(vNULL,vNULL,adCmdText);/执行指令,取得记录集 在这段代码中我们只是用Command对象来执行了SELECT查询语句,Command对象在

17、进行存储过程的调用中能真正体现它的作用。下次我们将具体介绍。 (3)挺直用Recordset对象进行查询取得记录集 实例- void CGmsaDlg:OnDBSelect() / TODO: Add your control notification handler code here _RecordsetPtr Rs1; /定义Recordset对象 _bstr_t Connect(“DSN=GMS;UID=sa;PWD=;”);/定义连接字符串 _bstr_t Source (“SELECT count(*) FROM buaa.mdb010”); /要执行的SQL语句 :CoIniti

18、alize(NULL); /初始化Rs1对象 HRESUL hr = Rs1.CreateInstance( _uuidof( Recordset ) ); /省略对返回值hr的推断 Rs1-Open( Source, Connect, adOpenForwardOnly, adLockReadOnly, -1 ); _variant_t temp=Rs1-GetCollect(_variant_t(long)0); CStringstrTemp=(char* )(_bstr_t)temp; MessageBox(“OK!”+strTemp); 例如 m_pRecordset-Open(“SE

19、LECT * FROM users”, _variant_t(IDispatch *)m_pConnection,true), adOpenStatic, adLockOptimistic, adCmdText); Open方法的原型是这样的: HRESULT Recordset15:Open ( const _variant_t Source, const _variant_tActiveConnection, enumCursorTypeEnumCursorType, enumLockTypeEnumLockType, long Options ) 其中: Source是数据查询字符串 A

20、ctiveConnection是已经建立好的连接(我们需要用Connection对象指针来构造一个_variant_t对象) CursorType光标类型,它可以是以下值之一,请看这个枚举结构: enumCursorTypeEnum adOpenUnspecified = -1,/不作格外指定 adOpenForwardOnly = 0,/前滚静态光标。这种光标只能向前扫瞄记录集,比如用MoveNext向前滚动,这种方 式可以提高扫瞄速度。但诸如BookMark,RecordCount,AbsolutePosition,AbsolutePage都不能用法 adOpenKeyset = 1,/采

21、纳这种光标的记录集看不到其它用户的新增、删除操作,但对于更新原有记录的操 作对您是可见的。 adOpenDynamic = 2,/动态光标。全部数据库的操作都会立刻在各用户记录集上反应出来。 adOpenStatic = 3/静态光标。它为您的记录集产生一个静态备份,但其它用户的新增、删除、更新操作对您 的记录集来说是不行见的。 ; LockType锁定类型,它可以是以下值之一,请看如下枚举结构: enumLockTypeEnum adLockUnspecified = -1,/未指定 adLockReadOnly = 1,/只读记录集 adLockPessimistic = 2,悲观锁定方式

22、。数据在更新时锁定其它全部动作,这是最平安的锁定机制 adLockOptimistic = 3,乐观锁定方式。只有在您调用Update方法时才锁定记录。在此之前仍旧可以做 数据的更新、插入、删除等动作 adLockBatchOptimistic = 4,乐观分批更新。编辑时记录不会锁定,更改、插入及删除是在批处理模 式下完成。 ; Options可以取如下值之一: adCmdText:表明CommandText是文本指令 adCmdTable:表明CommandText是一个表名 adCmdProc:表明CommandText是一个存储过程 adCmdUnknown:未知 5.记录集的遍历、更

23、新 依据我们刚才通过执行SQL指令建立好的users表,它包含四个字段:ID,username,old,birthday 以下的代码实现:打开记录集,遍历全部记录,删除第一条记录,添加三条记录,移动光标到其次条记录, 更改其年龄,保存到数据库。 _variant_tvUsername,vBirthday,vID,vOld; _RecordsetPtrm_pRecordset; m_pRecordset.CreateInstance(“ADODB.Recordset”); m_pRecordset-Open(“SELECT * FROM users”, _variant_t(IDispatch*

24、)m_pConnection,true), adOpenStatic, adLockOptimistic, adCmdText); while(!m_pRecordset-adoEOF) vID = m_pRecordset-GetCollect(_variant_t(long)0);/取得第1列的值,从0开头计数, /您也可以挺直给出列的名称,如下一行 vUsername = m_pRecordset-GetCollect(“username”);/取得username字段的值 vOld = m_pRecordset-GetCollect(“old”); vBirthday = m_pRec

25、ordset-GetCollect(“birthday”); /在DEBUG方式下的OUTPUT窗口输出记录集中的记录 if(vID.vt != VT_NULL vUsername.vt != VT_NULL vOld.vt != VT_NULL vBirthday.vt != VT_NULL) TRACE(“id:%d,姓名:%s,年龄:%d,生日:%s “, vID.lVal, (LPCTSTR)(_bstr_t)vUsername, vOld.lVal, (LPCTSTR)(_bstr_t)vBirthday); m_pRecordset-MoveNext();/移到下一条记录 m_pR

26、ecordset-MoveFirst();/移到首条记录 m_pRecordset-Delete(adAffectCurrent);/删除当前记录 /添加三条新记录并赋值 for(inti=0;i3;i+) m_pRecordset-AddNew();/添加新记录 m_pRecordset-PutCollect(”ID“,_variant_t(long)(i+10); m_pRecordset-PutCollect(”username“,_variant_t(”叶利钦“); m_pRecordset-PutCollect(”old“,_variant_t(long)71); m_pRecord

27、set-PutCollect(”birthday“,_variant_t(”1930-3-15“); m_pRecordset-Move(1,_variant_t(long)adBookmarkFirst);/从第一条记录往下移动一条记录,即移动 到其次条记录处 m_pRecordset-PutCollect(_variant_t(”old“),_variant_t(long)45);/修改其年龄 m_pRecordset-Update();/保存到库中 备注:多次查询可把查询过程做成一个函数ExecuteSQL让m_pRecordset获得连接指针m_pConnection查询结果 void

28、 ExecuteSQL(_ConnectionPtrm_pConnection, _RecordsetPtrm_pRecordset,CStringstrSql) /执行Select 语句 BSTR bstrSQL = strSql.AllocSysString(); try m_pRecordset-Open(bstrSQL,(IDispatch*)m_pConnection,adOpenDynamic,adLockOptimistic, adCmdText); /adOpenDynamic:动态 adLockOptimistic乐观封锁法 adCmdText:文本查询语句 catch(_c

29、om_error error) CStringerrorMessage; errorMessage.Format(”%s“,(LPTSTR)error.Description(); AfxMessageBox(errorMessage); /出错处理: 3127-没有找到目标表 3092-目标表已经存在 例如: catch(const _com_error e) AfxMessageBox(e.Description(); long errorCode=e.WCode(); if(3127=errorCode) AfxMessageBox(”表不存在“); if(3092=errorCode) AfxMessageBox(”表已经存在“); return FALSE; 更多信息请查看IT技术专栏 .

展开阅读全文
相关资源
猜你喜欢
相关搜索

当前位置:首页 > 社会民生


经营许可证编号:宁ICP备18001539号-1