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)
页面执行时间:207.404毫秒