Database 版 (精华区)
作 家: baby (心月) on board 'database'
题 目: 数 据 库 中 的 ODBC编 程 (3)
来 源: 哈尔滨紫丁香站
日 期: Thu Jun 26 10:05:42 1997
出 处: bbs@bbs.orange.sjtu.edu.cn
发信人: sibone (硅猫), 信区: database
标 题: 数 据 库 中 的 ODBC编 程 (3)
发信站: 饮水思源站 (Fri Mar 28 00:22:40 1997) , 站内信件
三 、 ODBC技 术 的 编 程 方 法
Visual C+ + 2 . 0 的 基 本 类 库 MFC 3 . 0 ( Microsoft Foundation
Class) 定 义 了 一 个 数 据 库 类 。 在 利 用ODBC编 程 时 , 要 经 常 用 到
数 据 库 类 中 的 CDatabase类 ( 数 据 库 类 ) 、 CRecordView类 ( 可 视 记
录 类) 和 CRecordSet( 记 录 集 类 ) 。 其 中 CRecordSet类 是 通 过 MFC支 持
ODBC的 关 键 , 它 封 装 了 操 纵ODBC表 所 需 的 各 种 函 数 。
1 . 使 用 AppWizard自 动 生 成 一 个 ODBC应 用 程 序 框 架
Visual C+ + 2 . 0 中 , AppWizard通 过 创 建 一 个 新 的 项 目 (
Project) 而 被 激 活 , 选 择 File菜 单 中 的New选 项 , 选 取 Project, 输 入
文 件 名 为 exodbc, 选 择 OK, 就 开 始 自 动 创 建 一 个 新 项 目 , 在 随
后的 步 骤 中 , 要 选 择 “ A database view, without file support” 选 项 或
“ Both a database view and file support” 选 项, 从 而 创 建 一 个 支 持
ODBC的 应 用 程 序 , 然 后 选 取 数 据 源 和 表 , 本 例 中 数 据 源 为
member, 表名 为 member. dbf, 其 他 的 步 骤 和 创 建 一 般 的 应 用 程 序 相
同 , 最 后 生 成 的 主 要 类 有 :CExodbcSet( CRecordset的 派 生 类 ) 、
CExodbcView( CRecordView的 派 生 类 ) 、 CExodbcDoc( CDocument的派 生 类 ) 。
2 . 记 录 的 打 开 和 数 据 的 交 换
CExodbcView类 负 责 打 开 记 录 集 ; 它 包 含 一 个 指 向 CExodbcSet
对 象 的 指 针 m- pSet, 该 对 象 自身 又 是 CExodbcDoc文 档 类 的 一 个 成
员 函 数 , 它 们 之 间 的 具 体 关 系 为 :
Class CExodbcView: public CRecordView
{ public:
CExodbcSet* m- pSet;
}
Class CExodbcDoc: public CDocument
{ public:
CExodbcSet m- exodbcset;
}
void CExodbcView: : OnInitialUpdate( )
{ m- pSet= & GetDocument( ) - > m- exodbcset; / * 指 向 记 录 的 指
针 * /
CRecordView: : OnInitialUpdate( ) ;
}
记 录 的 打 开 用 Open函 数 , 其 格 式 为 :
CExodbcSet: : Open( UINT nOpenType= snapshot, LPCSTR lpszSql= NULL, DWORD
dwOptions= none) 该 函 数 负 责 打 开 数 据 库 的 记 录 集 并 读 取 第 一 条
记 录 。 nOpenType参 数 的 取 值 为 :
dynaset: 允 许 双 向 翻 滚 的 动 态 记 录 集 , 即 对 记 录 集 进 行
的 修 改 立 即 生 效 ;
snapshot: 允 许 双 向 翻 滚 的 静 态 记 录 集 , 即 对 记 录 集 进 行
的 修 改 直 到 该 记 录 集 被 重 新 打 开
或 查 询 时 才 生 效 ;
lpszSql: 是 一 个 包 含 一 条 SQL语 句 的 字 符 串 指 针 , 该 语 句
在 表 被 打 开 时 执 行 , 缺 省 值 为NULL;
dwOptions: 指 定 对 记 录 集 如 何 修 改 , 允 许 取 值 范 围 为 :
none: 允 许 添 加 、 更 新 和 删 除 操 作 , 缺 省 设 置 ;
appendOnly: 允 许 添 加 操 作 , 不 允 许 更 新 和 删 除 操 作 ;
readyOnly: 只 读 、 不 允 许 添 加 、 更 新 和 删 除 ;
记 录 被 打 开 后 , 可 以 用 下 列 函 数 遍 历 表 中 的 记 录 :
· Void CRecordset: : MoveFirst( ) — — 移 动 到 第 一 条 记 录
· Void CRecordset: : MoveLast( ) — — 移 动 到 最 后 一 条 记 录
· Void CRecordset: : MovePrev( ) — — 后 滚 一 条 记 录
· Void CRecordset: : MoveNext( ) — — 前 滚 一 条 记 录
· Void CRecordset: : Move( long lRows) — — lRows为 正 数 , 前 滚
lRows条 记 录 ; 否 则 , 后 滚 lRows条 记录 。
为 了 判 别 是 否 移 到 表 的 开 始 和 结 尾 , 可 以 用 下 列 函 数
来 判 别 :
· BOOL CRecordset: : IsBOF( ) — — 如 果 已 经 向 后 滚 动 到 第
一 条 记 录 前 , 或 者 记 录 集 中 已 没有 记 录 时 , 返 回 非 零 值 ; 否
则 , 返 回 零 值 。
· BOOL CRecordset: : IsEOF( ) — — 如 果 已 前 滚 到 最 后 一 条 记
录 后 , 或 者 记 录 集 中 没 有 记 录时 , 返 回 非 零 值 ; 否 则 , 返 回
零 值 。
记 录 被 成 功 打 开 后 , GetDefaultConnect函 数 返 回 一 个 字 符 串
, 字 符 串 中 包 含 记 录 集 数 据 源名 称 。
CString CExodbcSet: : GetDefaultConnect( )
{ return - T( ″ ODBC; DSN= member; ″ ) }
字 符 串 前 面 的 “ ODBC; ” 标 识 该 数 据 源 是 一 个 ODBC的 数 据 源 ,
DSN( Date Source Name) 后 面 是数 据 源 名 称 。
CString CExodbcSet: : GetDefaultSQL( )
{ return - T( ″ member″ ) ; }
DetDefaultSQL( ) 函 数 返 回 记 录 集 所 使 用 的 数 据 源 中 的 表 的
名 称 ( 本 例 中 表 为 member. dbf) 。
DoFieldExchange函 数 用 于 在 记 录 集 的 成 员 变 量 和 ODBC驱 动 程
序 之 间 进 行 数 据 传 递 。 当 记录 被 读 取 时 , RFX… 函 数 将 数 据 从
数 据 库 中 传 递 到 成 员 变 量 中 。 当 添 加 和 更 新 记 录 时 ,同 样 用
这 些 函 数 把 应 用 程 序 中 的 数 据 传 递 到 数 据 库 中 。
Void CExodbcSet: : DoFieldExchange( CFieldExchange * pFX)
{ / / { { AFX- FIELD- MAP( CExodbcSet)
pFX- > SetFieldType( cFieldExchange: : outputColumn) ;
RFX- Text( pFX, ″ NAME″ , m- NAME) ; / * 和 姓 名 字 段 交 换 数
据 * /
RFX- Long( pFX, ″ AGE″ , m- AGE) ; / * 和 年 龄 字 段 交 换 数 据
* /
RFX- Text( pFX, ″ SEX″ , m- SEX) ; / * 和 性 别 字 段 交 换 数 据
* /
RFX- Text( pFX, ″ SECTION″ , m- SECTION) ; / * 和 部 门 字 段 交
换 数 据 * /
RFX- Long( pFX, ″ SALARY″ , m- SALARY) ; / * 和 工 资 字 段 交 换
数 据 * /
/ / } } AFX- FIELD- MAP
}
3 . 增 加 记 录
当 CRecordSet: : Open( ) 函 数 是 用 允 许 增 加 的 方 式 ( 即
dwOptions= none) 打 开 数 据 库 时 , 记 录 中的 CRecordSet对 象 将 标 记 那
些 被 绑 定 到 数 据 库 中 各 列 的 成 员 变 量 的 初 始 值 , 当 Update成
员 函数 被 调 用 时 , CRecordSet自 动 把 增 加 结 果 传 递 到 表 中 。
AddNew( ) 函 数 用 来 添 加 一 条 新 记 录 , 它 将 该 新 记 录 的 所
有 字 段 标 记 为 NULL和 未 修 改 ,然 后 调 用 UpdateData函 数 , 更 新 屏
幕 上 的 字 段 , 再 调 用 CRecordSet: : Update函 数 , 就 能 将 新 记录 写
入 数 据 库 中 , 具 体 的 函 数 为 :
void CExodbcDoc: OnRecordAdd( ) / * 增 加 记 录 的 响 应 函 数 * /
{
POSITION p;
CRecordView* view;
p= GetFirstViewPosition( ) ;
view= ( CRecordView* ) GetNextView( p) ;
m- exodbcset. AddNew( ) ; / * 在 表 的 末 尾 处 增 加 一 个 新 的 记
录 * /
view- > UpdateData( FALSE) ; / * 更 新 屏 幕 上 的 字 段 内 容 * /
view- > OnMove( ) ; / * 将 当 前 处 理 的 记 录 写 入 数 据 库 中 * /
}
BOOL CExodbcView: : OnMove( UNIT nIDMoveCommand)
{ CExodbcDoc* doc= GetDocument( ) ; / * 指 向 文 档 类 的 指 针 * /
m- pSet- > Update( ) ; / * 将 新 记 录 写 入 数 据 库 中 * /
m- pSet- > Requery( ) ; / * 根 据 输 入 的 新 记 录 , 重 建 记 录
集 * /
UpdateData( FALSE) ; / * 重 新 显 示 屏 幕 上 的 字 段 值 * /
return TRUE;
}
4 . 删 除 记 录
删 除 一 个 记 录 时 , 将 记 录 指 针 移 动 到 待 删 除 的 记 录 处 ,
然 后 调 用 Delete( ) 函 数 , 并 且 在调 用 Delete后 不 需 调 用 Update函 数
, 源 程 序 为 :
Void CExodbcDOC: : OnRecordDelete( ) / * 删 除 记 录 的 菜 单 响 应 函 数 * /
{ try { m- exodbcset. Delete( ) } ; / * 删 除 当 前 的 记 录 * /
catch( CDBException * e) { / * 出 现 异 常 , 给 出 提 示 * /
AfxmessageBox( ″ 不 能 删 除 一 个 记 录 ″ ) ; / * 指 出 删 除 操
作 失 败 * /
AfxmessageBox( e- > m- strError) ; / * 指 出 错 误 的 原 因 * /
return; }
if( ! m- exodbcset. IsEOF( ) ) / * 如 果 不 是 第 一 个 记 录 被 删
除 * /
m- exodbcSet. MoveNext( ) ; / * 记 录 指 针 定 位 到 下 一 个 记
录 * /
else/ * 最 后 一 个 记 录 被 删 除 * /
m- exodbcset. MoveLast( ) ; / * 记 录 指 针 定 位 到 上 一 个 记
录 * /
}
5 . 修 改 记 录
打 开 数 据 库 , 将 记 录 指 针 指 向 被 修 改 的 记 录 处 , 调 用
Edit成 员 函 数 , 就 可 以 修 改 该 记录 , 修 改 完 成 后 , 调 用 Update
函 数 将 修 改 结 果 传 递 到 数 据 库 中 。
m- exodbcSet. Open( ) ;
if( ! mexodbcset. CanUpdate( ) ) { / * 判 断 记 录 集 是 否 允 许 被 更 新 * /
m- exodbcset. Close( ) ;
return;
}
m- exodbcset. OnMove( ) ; / * 移 动 记 录 指 针 * /
m- exodbcset. Edit( ) ; / * 修 改 屏 幕 上 的 当 前 记 录 * /
m- exodbcset. Update( ) ; / * 将 修 改 的 结 果 写 入 数 据 库 中 * /
--
※ 来源:·饮水思源站 bbs.sjtu.edu.cn·[FROM: 202.120.16.126]
--
※ 来源:·哈尔滨紫丁香站 bbs1.hit.edu.cn·[FROM: bbs@bbs.orange.sjtu.]
Powered by KBS BBS 2.0 (http://dev.kcn.cn)
页面执行时间:208.315毫秒