《2022年直接通过ADO操作Access数据库 .pdf》由会员分享,可在线阅读,更多相关《2022年直接通过ADO操作Access数据库 .pdf(7页珍藏版)》请在taowenge.com淘文阁网|工程机械CAD图纸|机械工程制图|CAD装配图下载|SolidWorks_CaTia_CAD_UG_PROE_设计图分享下载上搜索。
1、直 接 通过ADO 操 作 Access数 据 库要 给 大家 介绍 的是ADO 数 据库 访问 技术 的 使用 方法 。 ADO(Active Data Object, 活动 数 据对 象 ) 实 际上 是一 种基于COM( 组件 对 象模 型 )的自 动 化接 口 (IDispatch)技术 , 并 以OLE DB( 对 象 连 接和 镶入 的数 据库 )为基 础 ,经过OLE DB 精 心包 装后 的数 据 库访 问技 术,利 用 它可 以快 速的 创建 数据 库 应用 程序 。ADO 提 供了 一组 非常 简单 ,将 一 般通 用的 数据 访 问细 节进 行封 装的 对象 。由 于 O
2、DBC 数 据源 也提 供了 一 般的OLE DB Privider,所 以ADO 不 仅可 以应 用自 身的OLE DB Privider,而且 还可 以应 用所 有的 ODBC 驱动 程序。关于 OLE DB 和 ADO 的 其它 详细 情况 ,读 者 可以 自行 查阅 相关 书籍 或 MSDN, 这 里就 不一一 说 明了。让我们直 接 步入 主题:如何掌握ADO 这 种数 据库 访问 技 术。 ADO 的操 作方 法和 前 面讲 过的DAO 的 操作 在很 多方 面存 在相 似之 处,在这 里,笔者为了 更有 效的 说明 它的 使 用方 法,用VC6.0 做 了一 个示 例程 序 Ad
3、oRWAccess,这 个示 例程 序可 以 直接 通过 ADO 来 操作 Access 数 据库 ,示 例程 序的 运行 效 果如 下图 所示 :在 示 例程 序中 我们 仍采 用原 库 结构, 数据 库名 Demo.mdb, 库内 表名 DemoTable,表 内字 段 名为Name( 姓 名 )和 Age( 年 龄 )的 两个 字段 ,来 构造 示例 程 序操 作所 需的 Access数据 库 ,这 也和 上两 篇文 章的 示 例源 码中 的库 结构 相兼 容 。下 面 让我 们看看ADO 数据 库访 问技 术使 用的 基本 步 骤及 方法 :名师资料总结 - - -精品资料欢迎下载 -
4、 - - - - - - - - - - - - - - - - - 名师精心整理 - - - - - - - 第 1 页,共 7 页 - - - - - - - - - 首 先 ,要 用 #import语句 来引 用支 持 ADO 的组 件类 型库 (*.tlb), 其中 类型 库可 以作为 可 执行 程序 (DLL 、 EXE 等 )的 一部 分被 定位 在其 自 身程 序中 的附 属资 源里 ,如:被定位在 msado15.dll的附 属 资源 中 ,只 需要 直接 用 #import引用 它 既可 。可以 直接在Stdafx.h文 件 中加 入下 面语 句来 实现 :#import c
5、:program filescommon filessystemadomsado15.dll no_namespace rename (EOF, adoEOF) 其 中 路径 名可 以根 据自 己系 统 安装的ADO 支 持文 件 的路 径来 自行 设定 。当 编 译器 遇到#import语 句时 ,它 会为 引用 组 件类 型库 中的 接口 生成 包 装类 , #import语句 实际 上相当 于 执行了API 涵数 LoadTypeLib()。#import语句 会在 工 程可 执行 程序 输出 目录 中产 生两 个 文件 ,分 别为 *.tlh(类 型库 头文 件 )及 *.tli(类
6、型库 实现 文件 ) ,它 们分 别为 每一 个接 口产 生 智能 指针 ,并 为各 种接 口 方法 、枚 举类 型, CLSID 等 进 行声 明, 创建 一系 列包 装 方法 。 语句no_namespace说明 ADO 对 象不 使用 命名 空 间, rename (EOF, adoEOF)说 明将 ADO 中 结束 标志EOF 改为adoEOF , 以避 免 和其 它库 中命 名相 冲突 。其 次 ,在 程序 初始 过程 中需 要初 始 化组 件, 一般 可以用CoInitialize(NULL);来 实现 ,这 种 方法 在结 束时 要关 闭初 始 化的 COM, 可 以用 下面 语
7、句CoUnInitialize();来实 现。 在MFC 中 还可 以采 用另 一种 方法 来实 现 初始化COM ,这种 方 法只 需要 一条 语句 便可 以自 动为 我 们实 现初 始化 COM 和 结束 时关 闭 COM 的操 作 ,语 句如 下所 示:AfxOleInit(); 接 着 ,就 可以 直接 使用 ADO 的 操作 了。 我们 经常 使用 的 只是 前面 用 #import语句 引用 类 型库 时,生 成的 包装 类 .tlh中 声明 的智 能指 针中 的三 个,它们 分别 是 _ConnectionPtr、_RecordsetPtr和 _CommandPtr。 下 面分
8、别对 它们 的使 用方 法进 行 介绍 :1、_ConnectionPtr智能 指针 ,通 常 用于 打开 、关 闭一 个库 连 接或 用它的Execute方法 来执 行 一个 不返 回结 果的 命令 语 句( 用法 和 _CommandPtr中的 Execute方 法类 似 )。打 开 一个 库连 接。先创 建一 个实 例 指针 ,再用Open 打 开一 个库 连接 ,它 将返 回一 个IUnknown的 自 动化 接口 指针 。代 码如 下 所示 :_ConnectionPtr m_pConnection; / 初 始 化 COM, 创 建 ADO连 接 等 操作AfxOleInit();
9、 m_pConnection.CreateInstance(_uuidof(Connection); / 在 ADO操作 中 建 议语 句中 要常 用 try.catch()来捕 获错 误信 息,/ 因 为 它有时 会经 常出现 一 些意 想不 到 的 错误 。 jingzhou xu try / 打开 本 地 Access 库 Demo.mdb m_pConnection-Open(Provider=Microsoft.Jet.OLEDB.4.0;Data Source=Demo.mdb,adModeUnknown); 名师资料总结 - - -精品资料欢迎下载 - - - - - - - -
10、 - - - - - - - - - - 名师精心整理 - - - - - - - 第 2 页,共 7 页 - - - - - - - - - catch(_com_error e) AfxMessageBox(数 据库 连接 失败 , 确 认数 据 库 Demo.mdb 是 否 在当 前路 径下 !); return FALSE; 关 闭 一个 库连 接。如 果 连接 状态 有效,则用Close 方法 关闭 它并 赋 于它 空值。代码如下 所 示:if(m_pConnection-State) m_pConnection-Close(); m_pConnection= NULL; 2、 _R
11、ecordsetPtr智能 指针 , 可以 用来 打开 库内 数据 表, 并 可以 对表 内的 记录 、字 段等进 行 各种 操作 。打 开 数据 表。 打开 库内 表名 为 DemoTable的数 据表 ,代 码如 下:_RecordsetPtr m_pRecordset; m_pRecordset.CreateInstance(_uuidof(Recordset); / 在 ADO操作 中 建 议语 句中 要常 用 try.catch()来捕 获错 误信 息,/ 因 为 它有时 会经 常出现 一 些意 想不 到 的 错误 。 jingzhou xu try m_pRecordset-Ope
12、n(SELECT * FROM DemoTable, / 查 询 DemoTable 表中 所有 字段theApp.m_pConnection.GetInterfacePtr(), / 获 取库 接库 的 IDispatch指 针adOpenDynamic, adLockOptimistic, adCmdText); catch(_com_error *e) AfxMessageBox(e-ErrorMessage(); 读 取 表内 数据 。将 表内 数据 全部 读 出并 显示 在列 表框 内, m_AccessList为列 表框 的成 员 变量 名。 如果 没有 遇到 表 结束 标志 ad
13、oEOF , 则用GetCollect(字 段名 )或名师资料总结 - - -精品资料欢迎下载 - - - - - - - - - - - - - - - - - - 名师精心整理 - - - - - - - 第 3 页,共 7 页 - - - - - - - - - m_pRecordset-Fields-GetItem(字 段名 )-Value方法 ,来获 取当 前记 录指 针所 指的 字段 值 ,然 后再用MoveNext()方 法移 动到 下 一条 记录 位置 。代 码如 下所 示 :_variant_t var; CString strName,strAge; try if(!m_p
14、Recordset-BOF) m_pRecordset-MoveFirst(); else AfxMessageBox(表 内数 据为 空); return; / 读入 库中 各字段 并加入 列 表框 中while(!m_pRecordset-adoEOF) var = m_pRecordset-GetCollect(Name); if(var.vt != VT_NULL) strName = (LPCSTR)_bstr_t(var); var = m_pRecordset-GetCollect(Age); if(var.vt != VT_NULL) strAge = (LPCSTR)_bst
15、r_t(var); m_AccessList.AddString( strName + - +strAge ); m_pRecordset-MoveNext(); / 默认 列表 指向第 一项, 同 时移 动记 录指 针并 显示m_AccessList.SetCurSel(0); catch(_com_error *e) AfxMessageBox(e-ErrorMessage(); 名师资料总结 - - -精品资料欢迎下载 - - - - - - - - - - - - - - - - - - 名师精心整理 - - - - - - - 第 4 页,共 7 页 - - - - - - - -
16、- 插 入 记录。 可以 先用 AddNew()方 法新 增一 个空 记录 ,再用PutCollect(字 段名 ,值 ) 输入 每 个字 段的 值, 最后 再 Update()更 新到 库中 数据 既可 。 其中 变量 m_Name和 m_Age分 别 为姓 名及 年龄 编辑 框的 成 员变 量名 。代 码所 下所 示 :try / 写入 各字 段值m_pRecordset-AddNew(); m_pRecordset-PutCollect(Name, _variant_t(m_Name); m_pRecordset-PutCollect(Age, atol(m_Age); m_pRecor
17、dset-Update(); AfxMessageBox(插 入 成 功!); catch(_com_error *e) AfxMessageBox(e-ErrorMessage(); 移 动 记录 指针 。移 动记 录指 针可 以 通过MoveFirst()方法 移动 到 第一 条记 录、MoveLast()方 法移 动到 最后 一条 记录 、 MovePrevious()方 法移 动到 当前 记录 的前 一条 记录 、 MoveNext()方法 移动 到 当前 记录 的下 一条 记录 。但 我 们有 时经 常需 要随 意移 动记 录指 针 到任 意记 录位 置时 ,可 以 使用 Move(
18、 记 录 号 ) 方法 来实 现 ,注 意 : Move()方法 是相 对于 当 前记 录来 移动 指针 位置 的 ,正 值向 后移 动、 负值 向 前移 动, 如: Move(3),当 前记录 是 3 时, 它将 从记 录 3 开始 往后 再移 动 3 条记 录位 置。 代码 如下 所示 :try int curSel = m_AccessList.GetCurSel(); / 先将 指针 移向第 一条记 录 , 然后 就 可 以相 对 第一 条 记录 来随 意移 动记 录指 针m_pRecordset-MoveFirst(); m_pRecordset-Move(long(curSel);
19、 catch(_com_error *e) AfxMessageBox(e-ErrorMessage(); 名师资料总结 - - -精品资料欢迎下载 - - - - - - - - - - - - - - - - - - 名师精心整理 - - - - - - - 第 5 页,共 7 页 - - - - - - - - - 修 改 记录 中字 段值 。可 以将 记录 指 针移 动到 要修 改记 录的 位置 处 ,直 接用PutCollect(字 段名,值)将 新值 写入 并 Update()更 新数 据库 既可 。可 以用 上面 方法 移动 记录 指 针, 修改 字段 值代 码如 下 所示 :t
20、ry / 假设 对第 二条记 录进行 修 改m_pRecordset-MoveFirst(); m_pRecordset-Move(1); / 从 0 开 始m_pRecordset-PutCollect(Name, _variant_t(m_Name); m_pRecordset-PutCollect(Age, atol(m_Age); m_pRecordset-Update(); catch(_com_error *e) AfxMessageBox(e-ErrorMessage(); 删 除 记录 。删 除记 录和 上面 修改 记 录的 操作 类似 ,先 将记 录指 针 移动 到要 修改
21、记录的 位 置, 直接用Delete()方法 删除 它 并用Update()来 更新 数 据库 既可 。代 码如 下所 示:try / 假设 删除 第二条 记录m_pRecordset-MoveFirst(); m_pRecordset-Move(1); / 从 0 开 始m_pRecordset-Delete(adAffectCurrent); / 参 数adAffectCurrent为 删 除当 前 记 录m_pRecordset-Update(); catch(_com_error *e) AfxMessageBox(e-ErrorMessage(); 关 闭 记录 集。 直接用Clos
22、e方 法关 闭记 录集 并赋 于其 空值 。 代码 如下 所示 :m_pRecordset-Close(); m_pRecordset = NULL; 3、 CommandPtr智 能指 针, 可以 使 用 _ConnectionPtr或 _RecordsetPtr来 执行 任务 ,定义 输 出参 数, 执行 存储 过程 或 SQL 语 句。名师资料总结 - - -精品资料欢迎下载 - - - - - - - - - - - - - - - - - - 名师精心整理 - - - - - - - 第 6 页,共 7 页 - - - - - - - - - 执 行 SQL 语句 。先 创建 一个
23、_CommandPtr实例 指 针,再 将库 连接 和 SQL 语句 做为 参数 , 执行Execute()方 法既 可。 代 码如 下所 示:_CommandPtr m_pCommand; m_pCommand.CreateInstance(_uuidof(Command); m_pCommand-ActiveConnection = m_pConnection; / 将 库连 接 赋 于它m_pCommand-CommandText = SELECT * FROM DemoTable; / SQL语句m_pRecordset = m_pCommand-Execute(NULL, NULL,
24、adCmdText); / 执行 SQL语 句 ,返 回记 录集执 行 存储 过程 。执 行存 储过 程的 操 作和 上面 执行 SQL 语 句类 似, 不同 点 仅是CommandText参数 中不 再是 SQL 语 句,而是存储 过程 的 名字 ,如 Demo 。另 一个 不同 点就 是在 Execute()中参 数由 adCmdText(执行 SQL 语句 ),改为adCmdS toredProc来 执行存 储 过程 。如 果存 储过 程中 存 在输 入、 输出 参数 的话 , 需要 使用 到另 一个 智能 指针_ParameterPtr来逐 次设 置要 输入 、 输出 的参 数信 息,
25、 并将 其赋 于 _CommandPtr中Parameters参数 来传 递 信息 ,有 兴趣 的读 者可 以自 行 查找 相关 书籍或MSDN。 执 行存 储过 程 的代 码如 下所 示:_CommandPtr m_pCommand; m_pCommand.CreateInstance(_uuidof(Command); m_pCommand-ActiveConnection = m_pConnection; / 将库 连 接 赋于 它m_pCommand-CommandText = Demo; m_pCommand-Execute(NULL,NULL, adCmdStoredProc); 名师资料总结 - - -精品资料欢迎下载 - - - - - - - - - - - - - - - - - - 名师精心整理 - - - - - - - 第 7 页,共 7 页 - - - - - - - - -