CRecordset

CRecordset 对 象 代 表 从 一 个 数 据 源 选 择 的 一 组 记 录 的 集 合 , 被 称 作 “ 记 录 集 ” 。CRecordset 对 象 可 以 以 两 种 形 式 使 用 : 动 态 集 和 快 照 。 动 态 集 是 与 其 它 用 户 的更 新 保 持 同 步 的 动 态 数 据 集 。 快 照 是 数 据 的 静 态 视 图 。 每 一 种 形 式 都 代 表 打 开记 录 集 时 固 定 的 一 组 记 录 。 但 是 当 滚 动 到 动 态 集 中 的 一 个 记 录 时 , 动 态 集 将 反映 后 来 由 其 它 用 户 或 由 应 用 程 序 中 其 它 记 录 集 对 此 记 录 所 做 的 改 变 。

注 意 如 果 你 正 在 使 用 数 据 访 问 对 象 ( DAO) 类 , 而 不 是 打 开 数 据 库 连 接

( ODBC ) 类 , 请 使 用 类 C Dao Recordset 来 代 替 。

要 使 用 任 何 一 种 记 录 集 , 通 常 需 要 从 CRecordset 派 生 一 个 应 用 程 序 指 定 的 记 录集 类 。 记 录 集 从 一 个 数 据 源 中 选 择 记 录 , 然 后 你 就 可 以 :

  • 在 这 些 记 录 中 滚 动 。

  • 更 新 记 录 并 指 定 一 种 加 锁 模 式 。

  • 过 滤 记 录 集 , 以 获 得 那 些 从 数 据 源 中 选 择 出 来 的 可 利

    用 的 记 录 。

  • 给 记 录 集 排 序 。

  • 参 数 化 该 记 录 集 以 定 制 它 的 具 有 要 直 到 运 行 时 才 知 道

    的 信 息 的 选 项 。

要 使 用 你 的 类 , 打 开 一 个 数 据 库 并 构 造 一 个 记 录 集 对 象 , 给 构 造 函 数 传 递 一 个指 向 你 的 CDatabase 对 象 的 指 针 。 然 后 调 用 记 录 集 的 Open 成 员 函 数 , 在 此 你可 以 指 定 该 对 象 是 一 个 动 态 集 还 是 一 个 快 照 。 调 用 Open 来 从 数 据 源 中 选 择 数据 。 在 记 录 集 对 象 被 打 开 之 后 , 用 它 的 成 员 函 数 和 数 据 成 员 来 滚 动 和 操 作 记 录 。可 用 的 操 作 根 据 对 象 是 一 个 动 态 集 还 是 一 个 快 照 ( 这 依 赖 于 打 开 数 据 库 连 接

( ODBC ) 数 据 源 的 性 能 ) , 是 可 更 新 的 还 是 只 读 的 , 你 是 否 实 现 了 成 组 行 检取 而 不 同 。 为 了 刷 新 从 调 用 Open 以 来 可 能 被 改 变 或 添 加 的 记 录 , 可 以 调 用 对象 的 Requery 成 员 函 数 。 当 你 使 用 完 对 象 之 后 , 调 用 对 象 的 Close 成 员 函 数 , 并 销 毁 此 对 象 。

在 一 个 派 生 的 CRecordset 类 中 , 使 用 记 录 字 段 交 换 ( RFX ) 或 成 组 记 录 字 段 交换 ( Bulk RFX ) 来 支 持 读 取 和 更 新 记 录 字 段 。

#include <afxdb.h>

请 参 阅 CDatabase , CRecordView

CRecordset 类 成 员

m _hstmt 包 含 记 录 集 的 ODBC 语 句 句 柄 。 类 型 为 HSTMT

m_nFields 包 含 记 录 集 中 的 字 段 数 据 成 员 数 目 。 类 型 为 UINT

m_nParams 包 含 记 录 集 中 参 数 数 据 成 员 的 数 目 。 类 型 为 UINT m_pDatabase 包 含 一 个 指 向 CDatabase 对 象 的 指 针 , 提 供 该 指 针

将 记 录 集 连 接 到 一 个 数 据 源

m_strFilter 包 含 一 个 CString , 此 对 象 指 定 一 条 结 构 式 查 询 语言 ( SQL ) 的 WHERE 子 句 。 此 成 员 可 用 作 一 个过 滤 器 , 只 选 择 符 合 某 一 标 准 的 那 些 记 录

m_strSort 包 含 一 个 CString , 此 对 象 指 定 一 条 SQL ORDER BY 子 句 。 此 成 员 可 用 于 控 制 记 录 的 排 序

Construction

Crecordset 构 造 一 个 CRecordset 对 象 。 应 用 程 序 的 派 生 类 必须 提 供 一 个 调 用 此 函 数 的 构 造 函 数

Open 通 过 检 取 记 录 集 表 示 的 表 格 或 执 行 查 询 来 打 开 记

录 集

Close 关 闭 记 录 集 和 与 此 记 录 集 相 关 联 的 ODBC HSTM T

CanAppend 如 果 新 记 录 可 以 通 过 AddNew 成 员 函 数 增 加 到 记录 集 中 , 则 该 函 数 返 回 一 个 非 零 值

CanBookmark 如 果 记 录 集 支 持 书 签 则 函 数 返 回 一 个 非 零 值

CanRestart 如 果 可 以 调 用 Requery 来 再 次 运 行 记 录 集 的 查 询 , 则 该 函 数 返 回 一 个 非 零 值

CanScroll 如 果 应 用 程 序 可 以 滚 动 记 录 , 则 该 函 数 返 回 一 个非 零 值

CanTransact 如 果 数 据 源 支 持 事 务 , 则 该 函 数 返 回 一 个 非 零 值

CanUpdate 如 果 记 录 集 可 修 改 ( 应 用 程 序 可 以 增 加 、 修 改 或删 除 记 录 ) , 则 该 函 数 返 回 一 个 非 零 值

GetODBCFieldCount 返 回 记 录 集 中 的 字 段 数 目

GetRecordCount 返 回 记 录 集 中 的 记 录 数 目

GetStatus 获 取 记 录 集 的 状 态 : 读 取 记 录 的 索 引 , 以 及 是 否已 获 取 到 记 录 的 最 终 计 数

GetTableName 获 取 此 记 录 集 基 于 的 表 的 名 字

GetSQL 获 取 用 于 选 择 记 录 集 的 记 录 的 SQL 字 符 串

IsOpen 如 果 前 面 已 经 调 用 了 Open 函 数 , 则 此 函 数 返 回 一个 非 零 值

续 表

IsBOF 如 果 记 录 集 已 经 定 位 在 第 一 个 记 录 前 , 则 此 函 数返 回 一 个 非 零 值

IsEOF 如 果 记 录 集 已 经 定 位 在 最 后 一 个 记 录 后 , 则 此 函数 返 回 一 个 非 零 值

IsDeleted 如 果 记 录 集 定 位 在 一 个 已 删 除 的 记 录 上 , 则 该 函数 返 回 一 个 非 零 值

Recordset Update Operations

AddNew 为 增 加 新 记 录 作 准 备 。 调 用 Update 来 完 成 增 加

CancelUpdate 取 消 任 何 用 AddNew 或 Edit 操 作 指 定 的 未 决 定的 更 新

Delete 从 记 录 集 中 删 除 当 前 记 录 。 删 除 之 后 , 应 用 程序 必 须 显 式 地 滚 动 到 另 一 个 记 录

Edit 为 改 变 当 前 记 录 作 准 备 。 调 用 Update 来 完 成 编辑

Update 通 过 将 新 数 据 或 所 编 辑 的 数 据 保 存 到 数 据 源上 , 来 完 成 一 次 AddNew 或 Edit 操 作

Recordset Navigation Operations

GetBookMark 将 一 个 记 录 的 标 签 值 分 配 给 该 参 数 对 象

Move

将 记 录 集 双 向 定 位 到

的 记 录 的 位 置

MoveFirst

定 位 当 前 记 录 为 记 录

函 数 首 先 测 试 IsBOF

MoveLast

定 位 当 前 记 录 为 记 录

该 函 数 首 先 测 试 IsEOF

MoveNext 定 位 当 前 记 录 为 记 录 集 中 的 下 一 个 记 录 。 该函 数 首 先 测 试 IsEOF

MovePrev 定 位 当 前 记 录 为 记 录 集 中 的 第 一 个 记 录 。 该函 数 首 先 测 试 IsBOF

SetAbsolutePosition 将 记 录 集 定 位 到 与 指 定 的 记 录 数 相 对 应 的 位

SetBookmark 定 位 记 录 集 到 书 签 指 定 的 位 置

O the r Recordse t Operation s Cancel 取 消 一 次 异 步 操 作 或 一 次 来 自 第 二 线 程 的 处

FlushResultSet 当 使 用 一 个 预 定 义 的 查 询 时 , 如 果 有 另 外 一个 结 果 被 获 取 , 返 回 非 零 值

GetFieldValue 返 回 记 录 集 中 的 一 个 字 段 的 值GetODBCFieldInfo 返 回 记 录 集 中 各 字 段 的 指 定 类 别 的 信 息GetRowsetSize 返 回 在 一 次 单 个 获 取 中 你 要 获 取 的 记 录 数 目

G etRowsFetched 返 回 在 一 次 获 取 中 实 际 获 取 的 行 数

GetRowStatus 返 回 在 一 次 获 取 中 行 的 状 态

IsFieldDirty 如 果 在 当 前 记 录 中 的 指 定 字 段 被 改 变 , 则 返回 一 个 非 零 值

IsFieldNull 如 果 当 前 记 录 中 的 指 定 字 段 是 Nu l (l

则 返 回 非 零 值

没 有 值 ),

IsFieldNullable 如 果 当 前 记 录 中 的 指 定 字 段 可 被 设 置 为 Null

( 没 有 值 ) , 则 返 回 非 零 值

RefreshRowset 刷 新 指 定 行 的 数 据 和 状 态

Requery 再 次 运 行 记 录 集 的 查 询 来 刷 新 所 选 择 的 记 录

SetFieldDirty 标 记 当 前 记 录 中 的 指 定 字 段 是 被 改 变 的

续 表

SetFieldNull 设 置 当 前 记 录 中 的 指 定 字 段 的 值 为 Null ( 没有 值 )

SetLockingMode 将 加 锁 模 式 设 置 为 “ 乐 观 ” 加 锁 ( 缺 省 值 )

或 “ 悲 观 ” 加 锁 。 确 定 任 何 更 新 加 锁 记 录

SetParamNull 将 指 定 的 参 数 设 置 为 Null( 没 有 值 )

SetRowsetCursorPosition 将 游 标 定 位 在 记 录 集 中 的 指 定 行 上

Recordset Overridables

Check 用 来 检 查 从 一 个 ODBC API 函 数 返 回 的 代 码CheckRowSetError 用 来 处 理 在 获 取 记 录 期 间 产 生 的 错 误DoBulkFieldExchange 用 来 将 一 组 数 据 行 从 数 据 源 中 交 换 到 记 录 集

中 。 实 现 成 组 记 录 交 换 ( Bulk RFX )

DoFieldExchange 用 来 在 此 记 录 集 的 字 段 数 据 成 员 和 数 据 源 上

对 应 的 记 录 之 间 交 换 数 据 ( 双 向 ) 。 双 向 记录 字 段 交 换 ( RFX )

GetDefaultConnect 用 来 获 取 缺 省 的 字 符 串

GetDefaultSQL 用 来 获 取 要 执 行 的 缺 省 的 SQL 字 符 串

OnSetOptions 用 来 为 指 定 的 ODBC 语 句 设 置 选 项

SetRowsetSize 指 定 在 一 次 获 取 中 你 希 望 获 取 的 记 录 数 目

成 员 函 数

CRecordset::AddNew

virtual void AddNew(); throw( CDBException );

说 明

此 函 数 用 来 为 向 表 中 增 加 一 个 新 记 录 作 准 备 。 你 必 须 调 用 Requery 成 员 函 数 来查 看 刚 增 加 的 记 录 。 该 记 录 的 字 段 初 始 为 Null ( 在 数 据 库 术 语 中 , Null 意 味 着“ 没 有 值 ”,与 C + + 中 的 NULL 不 一 样 )。要 完 成 增 加 操 作 ,你 必 须 调 用 Update 成 员 函 数 。 Update 将 应 用 程 序 的 改 变 保 存 到 数 据 源 中 。

注 意 如 果 你 已 经 实 现 了 成 组 读 取 , 则 你 不 能 调 用 AddNow 。 这 将 导 致 失败 的 断 言 。 虽 然 类 CRecordset 不 提 供 用 于 更 新 成 组 数 据 行 的 机 制 , 但 是

你 可 以 使 用 ODBC API 函 数 SQLSetPos 来 编 写 你 自 己 的 函 数 。 有 关 如 何 做到 这 一 点 的 例 子 , 请 参 见 DBEFETCH 示 例 。

AddNew 利 用 记 录 集 的 字 段 数 据 成 员 准 备 了 一 个 新 的 空 记 录 。 在 应 用 程 序 调 用AddNew 之 后 , 你 可 以 在 记 录 集 的 字 段 数 据 成 员 中 设 置 所 想 要 的 值 ( 应 用 程 序不 必 为 此 调 用 Edit 函 数 ; Edir 仅 用 于 已 有 记 录 ) 。 当 应 用 程 序 后 来 调 用 Update 函 数 时 , 此 字 段 数 据 成 员 中 已 改 变 的 数 据 将 被 保 存 到 数 据 源 上 。

警 告 如 果 你 在 调 用 Update 之 前 滚 动 到 一 个 新 的 记 录 ,则 该 新 记 录 丢 失 , 并 且 不 会 给 出 警 告 。

如 果 数 据 源 支 持 事 务 ,则 应 用 程 序 可 以 使 AddNew 调 用 成 为 一 次 事 务 的 一 部 分 。要 获 取 更 多 有 关 事 务 的 信 息 , 请 参 见 类 CDatabase 。 值 得 注 意 的 是 , 在 调 用AddNew 之 前 你 必 须 调 用 CDatabase::BeginTrans。

重 点 对 于 动 态 集 , 新 记 录 增 加 到 记 录 集 中 作 为 最 后 一 个 记 录 。 新 增 加的 记 录 不 增 加 到 快 照 中 – – – 应 用 程 序 必 须 调 用 Requery 函 数 来 刷 新 此 记 录集 。

对 一 个 未 调 用 其 Open 函 数 的 记 录 集 , 调 用 AddNew 函 数 是 不 合 法 的 。 如 果 应用 程 序 对 一 个 不 可 向 其 插 入 新 记 录 的 记 录 集 调 用 AddNew 函 数 , 则 将 抛 出 一 个CDBException 异 常 。 应 用 程 序 可 通 过 调 用 CanAppend 函 数 来 确 定 此 记 录 集 是否 可 以 更 新 。

请 参 阅 CRecordse t::Edit , CRecordse t::Delete , CRecordse t::Update , CRecordse t::Requery , C Database::BeginTran s, CDBException

CRecordset:: CanAppend

BOOL CanAppend() const;

如 果 此 记 录 集 允 许 增 加 新 记 录 , 则 该 函 数 返 回 一 个 非 零 值 ; 否 则 返 回 值 为 0 。如 果 应 用 程 序 以 只 读 方 式 打 开 此 记 录 集 , 则 CanAppend() 将 返 回 0 。

说 明

此 成 员 函 数 用 来 确 定 先 前 打 开 的 记 录 集 是 否 允 许 应 用 程 序 通 过 调 用 AddNew 成员 函 数 来 增 加 新 记 录 。

请 参 阅 CRecordset::AddNew , CRecordset::Requery

CRecordset::CanBookmark

BOOL CanBookmark() const;

如 果 记 录 集 支 持 书 签 则 返 回 非 零 值 ; 否 则 返 回 0 。

说 明

此 成 员 函 数 用 来 确 定 此 记 录 集 是 否 允 许 用 书 签 来 标 记 记 录 。 此 函 数 独 立 于 Open 成 员 函 数 的 dwOptions 参 数 中 CRecordset::useBookmarks 选 项 。 CanBookmark 表 明 给 定 的 ODBC 驱 动 器 和 游 标 类 型 是 否 支 持 书 签 。

如 果 支 持 书 签 , CRecordset::useBookmark 表 明 书 签 是 否 会 是 有 效 的 。

注 意 单 正 向 记 录 集 不 支 持 书 签 。

请 参 阅 CRecordset::GetBookmark , CRecordset::SetBookmark

CRecordset::Cancel

void Cancel();

说 明

此 成 员 函 数 用 来 请 求 数 据 源 取 消 一 次 正 在 进 行 的 异 步 操 作 或 者 是 一 次 来 自 第 二线 程 的 处 理 。 值 得 注 意 的 是 , MFC ODBC 类 不 再 使 用 异 步 处 理 ; 要 执 行 一 次 异步 操 作 , 你 必 须 直 接 调 用 ODBC API 函 数 SQLSetConnectOption。 要 获 取 更 多的 信 息 , 请 参 见 “ ODBC SDK 程 序 员 指 南 ” 中 的 “ 异 步 执 行 函 数 ” 。

CRecordset::CancelUpdate

void CancelUpdate();

说 明

此 成 员 函 数 用 来 在 调 用 Update 之 前 , 取 消 任 何 由 Edit 或 AddNew 引 起 的 未 决定 的 更 新 。

注 意 对 于 使 用 成 组 行 检 取 的 记 录 集 , 此 成 员 函 数 不 能 使 用 , 因 为 这 样的 记 录 集 不 能 调 用 Edit , AddNew 或 Update。

如 果 能 够 进 行 自 动 检 查 脏 字 段 , 则 CancelUpdate 将 把 成 员 变 量 的 值 恢 复 到 调 用Edit 或 AddNew 之 前 的 值 ; 如 果 不 支 持 自 动 检 查 , 则 改 变 后 的 任 何 值 都 被 保 留 。缺 省 的 , 当 记 录 集 被 打 开 时 , 自 动 字 段 检 查 是 有 效 的 。 为 了 使 它 无 效 , 你 必 须指 定 Open 成 员 函 数 的 dwOption 参 数 中 的 CRecordset::noDirtyFieldCheck 。

请 参 阅 CRecordset::AddNew , CRecordset::Edit , CRecordset::Update

CRecordset::CanRestart BOOL CanRestart() const; 返 回 值

如 果 允 许 查 询 则 返 回 非 零 值 ; 否 则 返 回 0 。

说 明

此 成 员 函 数 用 来 确 定 记 录 集 是 否 允 许 通 过 调 用 Requery 成 员 函 数 来 重 新 开 始 它的 查 询 ( 刷 新 它 的 记 录 ) 。

请 参 阅 CRecordset::Requery

CRecordset::CanScroll

BOOL CanScroll() const;

返 回 值

如 果 记 录 集 允 许 滚 动 则 返 回 非 零 值 ; 否 则 返 回 0 。

说 明

此 成 员 函 数 用 来 确 定 记 录 集 是 否 允 许 滚 动 。

CRecordset::CanTransact BOOL CanTransact() const; 返 回 值

如 果 记 录 集 支 持 事 务 , 则 返 回 一 个 非 零 值 ; 否 则 , 返 回 值 为 0 。

说 明

此 成 员 函 数 用 来 确 定 此 记 录 集 是 否 支 持 事 务 。

请 参 阅 CDatabase::BeginTran s, CDatabase::CommitTrans, CDatabase::Rollback

CRecordset::CanUpdate BOOL CanUpdate() const; 返 回 值

如 果 记 录 集 可 更 新 , 则 返 回 一 个 非 零 值 ; 否 则 , 返 回 值 为 0 。

说 明

此 成 员 函 数 用 来 确 定 此 记 录 集 是 否 可 更 新 。

如 果 基 本 数 据 资 源 只 读 或 如 果 当 你 打 开 记 录 集 在 dwOptions 参 数 中 指 定

CRecordset:: readOnly 时 , 一 个 记 录 集 可 能 为 只 读 。

请 参 阅 CRecordset::Open , CRecordset::AddNew , CRecordset::Edit, CRecordset::Delete , CRecordset::Update

CRecordset::Check

virtual BOOL Check( RETCODE nRetCode ) const;

返 回 值

如 果 nRetCode 的 值 是 SQL_SUCCESS , SQL_SUCCESS_WITH_INFO ,

SQL_NO_DATA_ FOUND 或 SQL_NEED_DATA , 则 返 回 非 零 值 ; 否 则 返 回 0 。

参 数

nRetCode

是 一 个 ODBC API 函 数 的 返 回 代 码 。 有 关 的 细 节 , 请 参 见 说 明 部 分 。

说 明

此 成 员 函 数 用 来 检 查 从 一 个 ODBC API 函 数 返 回 的 代 码 。 下 面 的 列 表 给 出 了

nRetCode 可 能 的 值 :

N retCode Description

SQL_SUCCESS 函 数 成 功 完 成 ; 没 有 其 它 的 可 用 信 息

SQL_SUCCESS_WITH

_INFO SQL_NO_DATA_FOU N D

函 数 成 功 完 成 , 可 能 有 一 个 非 致 命 的 错 误 。 通过 调 用 SQLError 可 以 获 得 更 多 的 信 息

获 取 了 来 自 结 果 集 的 所 有 行

SQL_ERROR 函 数 失 败 。 调 用 SQLError 可 以 获 得 更 多 的 信 息

续 表

SQL_INVALID_HAND LE

接从

数 失 败 , 这 是 由 于 一 个 无 效 的

句 柄 或 语 句 句 柄 。 这 表 明 有 一

SQLError 无 法 获 得 其 它 的 信 息

SQL_STILL_EXECUTI

个 异 步 开 始 的 函 数 仍 然 在 执 行

N G

, 缺 省 的 MFC 从 来 都 不 会 将

Check , 因 为 M FC 只 使 用 同 步 处 理

SQL_NEED_DATA 当 处 理 一 个 语 句 时 , 驱 动 器 决 定 应 用 程 序 需 要

发 送 参 数 数 据 值

如 果 要 获 取 更 多 关 于 SQLError 的 信 息 , 请 参 见 “ ODBC SDK 程 序 员 指 南 。 ”

示 例

参 见 宏 AFX_ODBC_CALL 。

请 参 阅 AFX_ODBC_CALL

CRecordset::Chec k RowsetError

virtual void CheckRowsetError( RETCODE nRecCode );

参 数

nRetCode

一个 ODBC API 函 数 返 回 代 码 。 要 获 取 细 节 , 请 参 见 说 明 部 分 。

说 明

此 虚 成 员 函 数 用 来 处 理 当 记 录 被 获 取 时 发 生 的 错 误 , 在 成 组 行 处 理 中 它 也 适用 。 你 可 以 重 载 Chec k RowsetError 来 执 行 你 自 己 的 错 误 处 理 。

在 一 次 游 标 导 航 操 作 ( 如 Open , Requery 或 是 任 何 Move 操 作 ) 中 , Chec k RowsetError 是 被 自 动 调 用 的 。它 被 作 为 ODBC API 函 数 SQLEetendedFetch 的 返 回 值 传 递 。 下 面 的 列 表 给 出 了 nR et Code 参 数 的 可 能 取 值 :

N retCode Description

SQL_SUCCESS 函 数 成 功 完 成 ; 没 有 其 它 的 可 用 信 息

SQL_SUCCESS_WITH_I NFO SQL_NO_DATA_FOUN D

函 数 成 功 完 成 , 可 能 有 一 个 非 致 命 的 错 误 。 通过 调 用 SQLError 可 以 获 得 更 多 的 信 息

获 取 了 来 自 结 果 集 的 所 有 行

SQL_ERROR 函 数 失 败 。 调 用 SQLError 可 以 获 得 更 多 的 信

SQL_INVALID_HANDL E

SQL_STILL_EXECUTIN G

函 数 失 败 , 这 是 由 于 一 个 无 效 的 环 境 句 柄 、 连接 句 柄 或 语 句 句 柄 。 这 表 明 有 一 个 程 序 错 误 。从 SQLError 无 法 获 得 其 它 的 信 息

一 个 异 步 开 始 的 函 数 仍 然 在 执 行 。 值 得 注 意 的是 , 缺 省 的 , M FC 从 来 都 不 会 将 这 个 值 传 递给 CheckRowsetError , M FC 将 继 续 调 用SQLEetendedFetch , 直 到 它 不 再 返 回SQL_STILL_EXECUTING

请 参 阅 CRecordset::DoBulkFieldExchange, CRecordset::GetRowsetSize , CRecordset::SetRowsetSize , CRecordset::Move

CRecordset::Close virual void Close(); 说 明

此 成 员 函 数 用 来 关 闭 记 录 集 。 ODBC HSTMT 和 框 架 分 配 给 这 个 记 录 集 的 内 存都 将 被 释 放 。 通 常 在 调 用 Close 之 后 , 如 果 此 C++ 记 录 集 对 象 是 用 new 分 配 的 , 则 由 应 用 程 序 来 负 责 删 除 它 。

在 调 用 Close 之 后 , 应 用 程 序 可 再 次 调 用 Open 函 数 。 这 使 应 用 程 序 可 复 用 此对 象 。 另 一 方 式 是 调 用 Requery 。

示 例

// CRecordset::Close 的 示 例

// 构 造 一 个 快 照 对 象

CCutSet rsCustSet( NULL ); if ( !rsCustSet.Open( ) )

return FALSE;

// 适 用 快 照

// 关 闭 快 照

rsCustSet.Clost( ) ;

// 当 函 数 退 出 时 , 调 用 析 构 函 数

请 参 阅 CRecordset:: CRecordset, CRecordset::Open , CRecordset::Requery

CRecordset::CRecordset

CRecordset( CDatabase* pDatabase = NULL );

参 数

pDatabase

包 含 一 个 执 行 CDatabase 对 象 的 指 针 , 或 者 是 值 为 NULL 。 如 果 不 是

NULL , 并 且 还 没 有 调 用 CDatabase 对 象 的 Open 成 员 函 数 来 将 它 连 接 到数 据 源 上 , 则 记 录 集 试 图 在 它 自 己 的 Open 调 用 期 间 为 应 用 程 序 打 开 此CDatabase 对 象 。 如 果 此 参 数 为 NULL , 则 当 应 用 程 序 利 用 ClassWizard 来 派 生 自 己 的 记 录 集 类 时 , 将 使 用 应 用 程 序 所 指 定 的 数 据 源 信 息 来 构 造并 连 接 一 个 CDatabase 对 象 。

说 明

此 成 员 函 数 用 来 构 造 一 个 CRecordset 对 象 。 应 用 程 序 的 记 录 集 对 象 必 须 是 从CRecordset 派 生 的 应 用 程 序 专 用 类 的 对 象 。 可 以 利 用 ClassWizard 来 派 生 应 用程 序 自 己 的 记 录 集 类 。

注 意 应 用 程 序 的 派 生 类 必 须 提 供 它 自 己 的 构 造 函 数 。 在 此 构 造 函 数 中 , 需 要 传 递 适 当 的 参 数 来 调 用 构 造 函 数 CRecordset::CRecordset 。

传 递 NULL 参 数 给 你 的 记 录 集 构 造 函 数 , 可 以 为 应 用 程 序 自 动 构 造 并 连 接 一 个CDatabase 对 象 。 这 是 一 种 有 用 的 简 捷 方 式 , 它 不 需 要 应 用 程 序 在 构 造 自 己 的记 录 集 之 前 构 造 并 连 接 一 个 CDatabase 对 象 。

请 参 阅 CRecordset::Open , CRecordset::Close

CRecordset::Delete

virtual void Delete(); throw(CDBException);

说 明

此 成 员 函 数 用 来 删 除 当 前 记 录 。 在 成 功 删 除 之 后 , 此 记 录 集 的 字 段 数 据 成 员 被设 置 为 NULL 值 , 并 且 应 用 程 序 必 须 显 式 地 调 用 一 个 Move 函 数 来 移 走 所 删 除的 记 录 。 一 旦 移 走 了 被 删 除 的 记 录 , 就 不 能 再 恢 复 它 。 如 果 数 据 源 支 持 事 务 ,

则 可 以 使 Delete 调 用 成 为 一 次 事 务 的 一 部 分 。

注 意 如 果 你 已 经 实 现 了 成 组 读 取 , 则 不 能 调 用 Delete 。 这 会 导 致 一 个失 败 断 言 。 虽 然 类 CRecordset 不 提 供 用 于 更 新 成 组 数 据 行 的 机 制 , 但 是你 可 以 使 用 ODBC API 函 数 SQLSetPos 来 编 写 你 自 己 的 函 数 。 有 关 如 何 做到 这 一 点 的 例 子 , 请 参 见 DBEFETCH 示 例 。

警 告 当 你 调 用 Delete 时 , 记 录 集 必 须 被 更 新 , 并 且 当 前 在 记 录 集 中 必须 有 有 效 的 记 录 ; 否 则 将 发 生 错 误 。 例 如 , 如 果 你 删 除 了 一 个 记 录 , 但是 在 你 再 次 调 用 Delete 之 前 没 有 滚 动 到 一 个 新 的 记 录 , 则 Delete 会 抛出 一 个 CDBException。

与 AddNew 和 Edit 不 同 , Delete 调 用 后 不 跟 Update 调 用 。 如 果 Delete 调 用 失败 , 字 段 数 据 成 员 将 保 持 不 变 。

示 例

这 个 例 子 说 明 了 如 何 在 一 个 函 数 框 架 上 创 建 一 个 记 录 集 。 该 例 子 假 定 m_dbCust

存 在 , 一 个 CDatabase 类 型 的 成 员 变 量 已 经 连 接 到 数 据 源 上 。

// 创 建 一 个 派 生 的 CRecordset 对 象

CCustSet rsCustSet( &m_dbCust ); rsCustSet.Open( );

if ( rsCustSet.Is EO F ( ) || !rsCustSet.CanUpdate( ) || !rsCustSet.CanTransact( ) ) return ;

if( !m_dbCust.BeginTrans() )

{

// 做 某 些 事 情 来 处 理 一 个 失 败

}

else

{

// 可 能 是 滚 动 到 一 个 新 记 录 ...

// 删 除 当 前 记 录

rsCustSet.Delete( );

//

// 完 成 这 次 事 务 的 命 令

if ( < the user Confir ms the transaction > ) m_dbCust.CommitTrans( );

else // 用 户 改 变 了 主 意

.m_dbCust.Rollback( );

}

// ...

请 参 阅 Database ::BeginTran s, C Database ::CommitTran s, C Database ::Rollback , CDBException

CRecordset::DoBulkFieldExchange

virtual void DoBulkFieldExchange( CFieldExchange* pFX ); throw( CDBException );

参 数

pFX

  • 个 指 向 一 个 CFileExchange 对 象 的 指 针 。 框 架 已 经 设 置 了

    这 个 对 象 来 为字 段 交 换 操 作 指 定 一 个 环 境 。

说 明

当 实 现 了 成 组 行 处 理 时 , 框 架 调 用 这 个 成 员 函 数 来 将 数 据 从 数 据 源 自 动 传 输 到你 的 记 录 集 对 象 。 DoBulkFieldExchange 还 将 应 用 程 序 的 参 数 数 据 成 员 ( 如 果有 的 话 ) 与 记 录 集 选 择 的 SQL 语 句 字 符 串 中 的 参 数 占 位 符 绑 定 。

如 果 还 没 有 实 现 成 组 行 读 取 , 则 框 架 调 用 DoFieldExchange。 为 了 实 现 成 组 行读 取 , 你 必 须 指 定 Open 成 员 函 数 中 的 dwOptions 参 数 的CRecordset::useMultiRowFetch 选 项 。

注 意 只 有 在 你 正 使 用 一 个 从 CRecordset 派 生 来 的 类 时 , DoBulkFieldExchange 才 是 可 用 的 。 如 果 你 已 经 直 接 从 CRecordset 创 建了 一 个 记 录 集 对 象 , 则 你 必 须 调 用 GetFieldValue 成 员 函 数 来 获 取 数 据 。

成 组 记 录 字 段 交 换 ( Bulk RFX ) 与 记 录 字 段 交 换 ( RFX ) 类 似 。 数 据 被 自 动 地从 数 据 源 传 输 到 一 个 记 录 集 对 象 。 但 是 , 你 不 能 调 用 AddNew , Edit , Delete 或Update 来 将 改 变 传 输 回 数 据 源 。 目 前 类 CRecordset 不 提 供 用 于 更 新 数 据 成 组 行的 机 制 ; 但 是 , 你 可 以 用 ODBC API 函 数 SQLSetPos 来 编 写 你 自 己 的 函 数 。

值 得 注 意 的 是 , ClassWizard 不 支 持 成 组 记 录 字 段 交 换 ( RFX ) ; 因 此 , 你 必 须通 过 调 用 Bulk RFX 函 数 来 手 动 重 载 DoBulkFieldExchange 。 如 果 要 获 取 更 多 关于 这 些 函 数 的 信 息 , 请 参 见“ V isual C++ 联 机 文 档 ” 中 的“ 记 录 字 段 交 换 函 数 ”。

如 果 要 得 到 一 个 有 关 如 何 实 现 成 组 记 录 字 段 交 换 的 例 子 , 请 参 见 DBFETCH 示例 。 要 获 取 更 多 关 于 成 组 行 读 取 的 信 息 , 请 参 见 “ V isual C++ 程 序 员 指 南 ” 中

的 文 章 “ 记 录 集 : 按 组 读 取 记 录 ” ( ODBC ) 。

请 参 阅 CRecordset::m_nFields, CRecordset::m_nParam s,

CRecordset::Do F ieldExchange , CRecordset::GetFieldValue ,

CFieldExchange,

Record Field Exchange Functions

CRecordset::DoFieldExchange

virtual void DoFieldExchange( CFieldExchange* pFX ); throw( CDBException );

参 数

pFX

是 一 个 指 向 CFielsExchange 对 象 的 指 针 。 框 架 已 经 为 字 段 交 换 操 作 设 置了 这 个 对 象 来 指 定 一 个 环 境 。

说 明

当 还 没 有 实 现 成 组 行 读 取 时 , 框 架 调 用 这 个 成 员 函 数 来 在 记 录 集 的 字 段 数 据 成员 和 数 据 源 的 当 前 记 录 的 相 应 列 之 间 自 动 进 行 数 据 交 换 。 DoFieldExchange 还将 应 用 程 序 的 参 数 数 据 成 员 ( 如 果 有 的 话 ) 与 记 录 集 选 择 的 SQL 语 句 字 符 串 中的 参 数 占 位 符 绑 定 。

如 果 已 经 实 现 了 成 组 行 读 取 , 则 框 架 调 用 D o Bulk FieldExchange 。 为 了 实 现 成组 行 读 取 , 你 必 须 指 定 Open 成 员 函 数 中 的 dwOptions 的CRecordset::useMultiRowFetch 选 项 。

注 意 只 有 在 你 正 使 用 一 个 从 CRecordset 派 生 来 的 类 时Do Bulk FieldExchang e 才 是 有 效 的 。 如 果 你 已 经 直 接 从 CRecordset 创 建了 一 个 记 录 集 对 象 , 你 必 须 调 用 GetFieldValue 成 员 函 数 来 检 取 数 据 。

字 段 数 据 的 交 换 , 被 称 为 记 录 字 段 交 换 ( RFX ) , 可 以 双 向 工 作 : 从 记 录 集 对象 的 字 段 数 据 成 员 到 数 据 源 的 记 录 的 字 段 , 或 者 从 数 据 源 中 的 记 录 到 记 录 集 对象 。

应 用 程 序 为 实 现 应 用 程 序 派 生 记 录 集 类 的 DoFieldExchange 函 数 , 一 般 必 须 执行 的 唯 一 动 作 是 用 ClassWizard 创 建 此 派 生 记 录 集 类 , 并 指 定 字 段 数 据 成 员 的名 字 和 数 据 类 型 。 应 用 程 序 也 可 以 增 加 代 码 到 ClassWizard 编 写 的 代 码 中 , 以指 定 参 数 数 据 成 员 或 处 理 应 用 程 序 动 态 连 接 的 任 何 列 。

当 你 用 ClassWizard 声 明 你 的 记 录 集 类 的 时 候 , 该 向 导 会 为 你 重 载

DoFieldExchange, 这 类 似 于 下 面 的 例 子 :

void CCustSet::DoFieldExchange( CFieldExchange* pFX )

{

// { { AFX_FIELD_MAP( CCustSet )

PFX->SetFieldType( CFieldExchange::outputDColum ); RFX_Text( pFX, “ Nam e ” , m_strName );

RFX_Int( pFX, “ Age ” , m_wAge );

//} }AFX_FIELD_MAP

}

要 获 取 更 多 有 关 RFX 函 数 的 信 息 , 请 参 见“ V isual C++ 联 机 文 档 ”中 的 文 章“记录 字 段 交 换 : RFX 是 如 何 工 作 的 ” 。

请 参 阅 CRecordset::m_nFields, CRecordset::m_nParam s, CRecordset::DoBulkfieldExchange , CRecordset::GetFieldValue ,

CFieldExchange,

Record Field Exchange Functions

CRecordset::Edit

virtual void Edit();

throw( CDBException, CMemoryException );

说 明

此 成 员 函 数 用 来 支 持 对 当 前 记 录 的 修 改 。 当 应 用 程 序 调 用 Edit 之 后 , 就 可 以 通过 直 接 重 新 设 置 字 段 数 据 成 员 的 值 来 改 变 它 们 。 当 后 来 应 用 程 序 重 新 调 用Update 成 员 函 数 来 将 这 些 改 变 保 存 到 数 据 源 上 时 , 这 次 操 作 才 算 完 成 。

注 意 如 果 你 已 经 实 现 了 成 组 行 读 取 , 你 就 不 能 调 用 Edit。 这 将 导 致 一个 失 败 断 言 。 虽 然 类 CRecordset 不 提 供 用 于 更 新 成 组 数 据 行 的 机 制 , 但是 你 可 以 使 用 ODBC API 函数 SQLSetPos 来 编 写 你 自 己 的 函 数 。 有 关 如 何做 到 这 一 点 的 例 子 , 请 参 见 DBEFETCH 示 例 。

Edi t 保 存 记 录 集 的 数 据 成 员 的 值 。 如 果 你 调 用 了 Edit , 进 行 了 改 变 , 然 后 再 调用 Edit, 则 记 录 的 值 被 恢 复 到 第 一 次 调 用 Edit 之 前 的 值 。

在 某 些 情 况 下 , 你 可 能 会 想 通 过 将 一 个 列 置 为 Null 来 更 新 它 。 要 实 现 这 一 点 ,

可 以 使 用 TRUE 为 参 数 调 用 SetFieldNull 函 数 , 来 标 记 此 字 段 为 Null; 这 样 也使 此 字 段 表 列 被 更 新 。 如 果 你 想 要 将 某 一 字 段 写 入 数 据 源 , 即 使 是 它 的 值 没 有改 变 , 则 可 以 使 用 TRUE 为 参 数 调 用 SetFieldDirty 函 数 。 即 使 此 字 段 的 值 为Null, 这 也 同 样 可 行 。

如 果 数 据 源 支 持 事 务 , 则 应 用 程 序 可 以 让 Edit 成 为 事 务 的 一 部 分 。 值 得 注 意 的是 ,你 应 当 在 调 用 Edit 之 前 ,但 在 打 开 记 录 集 之 后 ,调 用 CDatabase::BeginTrans 函 数 。 还 要 注 意 , 调 用 CDatabase::CommitTrans 并 不 能 代 替 调 用 Update 来 完 成Edit 操 作 。 要 获 取 有 关 事 务 的 更 多 信 息 , 请 参 见 CDatabase 类。

根 据 当 前 的 加 锁 方 式 , 正 被 更 新 的 记 录 可 能 被 Edit 加 锁 , 直 到 应 用 程 序 调 用Update 或 滚 动 到 另 一 个 记 录 ; 也 可 能 它 只 在 Edit 调 用 期 间 被 加 锁 。 你 可 以 利 用SetLocking Mode 来 改 变 加 锁 方 式 。

如 果 应 用 程 序 在 调 用 Update 之 前 滚 动 到 了 一 个 新 的 记 录 , 则 恢 复 当 前 记 录 的 先

个 CDBException 异 常 。

示 例

// CRecordset::Edit 的 示 例

// 编 辑 一 个 记 录

// 首 先 设 置 编 辑 缓 存

// rsCustSet.Edit();

// 然 后 编 辑 记 录 的 字 段 数 据 成 员

rsCustSet.m_dwCustID = 2795; rsCustSet.m_strCustomer = “Jones Mfg ” ;

// 最 后 , 完 成 此 操 作

if ( !rsCustSet.Update() )

// 处 理 更 新 失 败

CRecordset::SetFieldDirty , CRecordset::SetFieldNull ,

CRecordset::CanUpdate ,

CRecordset::CanTransact , CRecordset::SetLockingMode

CRecordset::FlushResultSet

BOOL FlushResultSet() const; throw( CDBException );

返 回 值

如 果 获 取 了 多 个 结 果 集 , 则 返 回 非 零 值 ; 否 则 返 回 0 。

说 明

此 成 员 函 数 用 来 获 取 一 个 预 定 义 的 查 询 ( 被 保 存 的 过 程 ) 的 下 一 个 结 果 集 , 如

时 , 你 才 应 该 调 用 FlushResultSet 。 值 得 注 意 的 是 , 当 你 通 过 调 用 FlushResultSet 获 取 下 一 个 结 果 集 时 , 则 在 那 一 个 结 果 集 上 的 游 标 就 无 效 了 ; 你 应 当 在 调 用FlushResultSet 之 后 调 用 MoveNext 成 员 函 数 。

如 果 一 个 预 定 义 的 查 询 使 用 了 输 出 参 数 或 者 是 输 入 /输 出 参 数 , 则 为 了 得 到 这 些参 数 的 值 , 你 必 须 一 直 调 用 FlushResultSet 直 到 它 返 回 FALSE ( 值 0 ) 。

FlushResultSet 调 用 了 ODBC API 函 数 SQLMoreResult s。 如 果 SQLMoreResults 返 回 SQL_ERROR 或 SQL_INVALID_HANDLE ,则 FlushResultSet 将 抛 出 一 个异 常 。 要 获 取 有 关 SQLMoreResults 的 更 多 信 息 , 请 参 见 “ ODBC SDK 程 序 员参 考 ” 。

示 例

下 面 的 例 子 假 定 COutParamRecordset 是 一 个 基 于 预 定 义 查 询 的 Crecordset 的派生 对 象 , 该 查 询 具 有 一 个 输 入 参 数 和 一 个 输 出 参 数 , 并 且 有 多 个 结 果 集 。 注 意DoFieldExchange 重 载 的 结 构 。

// DoFieldExchange 重 载

//

// 只 有 在 处 理 参 数 装 订 时 才 有 必 要 。

// 不 要 使 用 有 边 界 字 段 的 CRecordset 派 生 类 ,

// 除 非 所 有 的 结 果 集 具 有 相 同 的 概 要

//或 者 是 有 条 件 的 装 订 代 码 。

void COutParamRecordset::DoFieldExchange( CFieldExchange* pFX );

{

pFX _ >SetFieldType( CFieldExchange::outputParam ); RFX_Long( pFX, “ Param l” , m_nOutParamInstructorCount );

// 在 此 “ Param l” 名 字 是 一 个 从 未 使 用 过 的 假 名 。

pFX->SetFieldType( CFieldExchange::inputParam ); RFX_Text( pFX, “ Param 2” , m_strInParamName );

}

// 现 在 实 现 COurParamRecordset 。

// 假定 db 是 一 个 已 经 打 开 的 数 据 库 对 象 。

COutParamRecordset rs( &db );

rs.m_strInParamName = _T (“ Some_Input_Param_value ” );

// 获 取 第 一 个 结 果 集

// 注 意 : 对 于 返 回 多 行 集 合 的 存 储 过 程 来 说 , SQL S erver 需 要 只 能 前 进 类 型的 游 标 。

rs.Open(CRecordset::forwardOnly,”

{? = CALL GetCourses( ? ) } ” , CRecordset::readOnly );

// 在 第 一 个 结 果 集 中 循 环 通 过 所 有 的 数 据

while( !rs.IsEOF( ) )

{

CString strFieldValue; for( int n In dex = 0 ;

nIndex < rs.GetODBCFieldCount( ); nIndex++ )

{

rs.GetFieldValue( nIndex, strFieldValue );

// TO DO : 使 用 字 段 值 字 符 串

}

rs.MoveNext( );

}

// 获 取 其 它 的 结 果 集 ...

while ( rs.FlushResultSet( ) )

{

// 由 于 游 标 无 效 , 必 须 定 义 MoveNext

rs.MoveNext( ); while( !rs.IsEOF( ) )

{

CString strFieldValue; for( int nIndex = 0;

nIndex < rs.GetODBCFieldCount( ) ; nIndex++ )

{

rs.GetFieldValue( nIndex, strFieldValue ); TO D O : 使 用 的 字 段 值 字 符 串 。

}

rs.MoveNext( );

}

}

// 所 有 的 结 果 集 都 满 了 。 不 能 使 用 该 游 标 了 ,

// 但 是 已 经 写 入 了 输 出 参 数 m_nOutParamInstructorCoun t。

// 注 意 , 要 直 到 CRecordset::FlushResultSet 返 回 FALSE ,

// 这 表 明 不 会 再 返 回 更 多 的 结 果 集 , 这 时 m_nOutParamInstructorCount 才 无效 。

// TO DO : 使 用 m_nOutParamInstructorCount

// 清除

rs.Close( );

db.Close( );

请 参 阅 CFieldExchange::SetFieldType

CRecordset::GetBookmark

void GetBookmark( CDBVariant& varBookmark ); throw( CDBException, CMemoryException );

参 数

varBookmark

一 个 指 向 CDBVariant 对 象 的 引 用 , 该 对 象 代 表 在 当 前 记 录 上 的 书 签 。

说 明

此 成 员 函 数 用 来 获 得 当 前 记 录 的 书 签 值 。 要 确 定 此 记 录 集 是 否 支 持 书 签 , 调 用

CanBookmark 。 如 果 支 持 书 签 , 应 用 程 序 要 使 书 签 有 效 , 就 必 须 设 置 Open 成员 函 数 中 的 dwOptions 的 CRecordset::useBookmarks 选 项 。

注 意 如 果 不 支 持 书 签 或 者 是 书 签 无 效 , 调 用 GetBookmark 将 导 致 抛 出一 个 异 常 。 在 只 向 前 的 记 录 集 中 是 不 支 持 书 签 的 。

GetBookmark 将 当 前 记 录 的 书 签 值 分 配 给 一 个 CDBVariant 对 象 。 在 移 动 到 另一 个 记 录 之 后 , 要 返 回 原 来 的 记 录 , 可 以 用 相 应 的 CDBVariant 对 象 来 调 用SetBookmark 。

注 意 在 进 行 了 一 定 的 记 录 集 操 作 后 , 书 签 也 许 就 不 再 有 效 了 。 例 如 , 如 果 你 在 调 用 GetBookmark 之 后 接 着 调 用 了 Requery , 你 也 许 就 不 能 再用 SetBookmark 返 回 原 来 的 记 录 了 。 调 用CDatabase::GetBookmarkPersistence 来 检 查 你 是 否 能 够 安 全 地 调 用SetBookmark 。

C Database ::GetBookmarkPersistence

CRecordset::GetDefaultConnect virtual CString GetDefaultConnect( ); 返 回 值

返 回 一 个 包 含 缺 省 连 接 字 符 串 的 CString 。

说 明

框 架 调 用 此 成 员 函 数 来 获 取 此 记 录 集 所 基 于 的 数 据 源 的 缺 省 连 接 字 符 串 。ClassWizard 通 过 在 ClassWizard 中 标 识 与 应 用 程 序 所 使 用 的 相 同 数 据 源 来 获 取有 关 表 和 列 的 信 息 , 为 应 用 程 序 实 现 GetDefaultConnect 函 数 。 你 可 能 会 发 现 依赖 这 样 的 缺 省 连 接 来 开 发 应 用 程 序 是 很 方 便 的 。 但 是 缺 省 连 接 可 能 不 适 合 于 你

ClassWizard 的 版 本 。

CRecordset::GetDefaultSQL virtual CString GetDefaultSQL( ); 返 回 值

返 回 一 个 包 含 缺 省 的 SQL 语 句 的 CString。

说 明

框 架 调 用 此 成 员 函 数 来 获 取 此 记 录 集 基 于 的 缺 省 的 SQL 语 句 。 它 可 能 是 一 个 表名 , 也 可 能 是 一 条 SQL SELECT 语 句 。

你 可 以 通 过 使 用 ClassWizard 来 声 明 自 己 的 记 录 集 类 ,来 间 接 地 定 义 缺 省 的 S Q L

如 果 你 需 要 自 己 的 SQL 语 句 串 , 就 调 用 GetSQ L, 它 返 回 用 来 选 择 记 录 集 的 记录 的 SQL 语 句 , 如 果 记 录 集 是 打 开 的 话 。 你 可 以 在 你 的 类 的 GetDefaultSQL 重载 中 编 辑 你 的 SQL 字 符 串 。 例 如 , 你 可 以 使 用 一 个 CALL 语 句 来 指 定 对 一 个预 定 义 的 查 询 的 调 用 。

警 告 如 果 框 架 不 能 标 识 一 张 表 的 名 字 或 提 供 了 多 个 表 名 , 亦 或 不 能 插入 一 个 CALL 语 句 , 则 表 名 将 是 空 的 。 注 意 , 当 使 用 CALL 语 句 时 , 你 不能 在 弯 括 号 和 CALL 关 键 字 之 间 插 入 空 格 , 也 不 能 在 弯 括 号 之 前 或 者 是SELECT 语 句 中 的 SELECT 关 键 字 之 前 插 入 空 格 。

请 参 阅 CRecordset::GetSQL

CRecordset::GetFieldValue

void GetFieldValue ( LPCTSTR lpszName , CDBVariant& varValue , short nFieldType = DEFAULT_FIELD_TYPE );

throw( CDBException, CMemoryException );

void GetFieldValue ( short nIndex , CDBVariant& varValue , short nFieldType = DEFAULT_FIELD_TYPE );

throw( CDBException, CMemoryException );

void GetFieldValue ( LPCTSTR lpszName , CString& strValue ); throw( CDBException, CMemoryException );

void GetFieldValue ( short nIndex , CString& strValue );

throw( CDBException, CMemoryException );

参 数

lpszName

  • 个 字 段 的 名 字 。

varValue

  • 个 指 向 CDBVariant 对 象 的 引 用 , 该 对 象 将 用 来 保 存 字 段

    的 值 。

nFieldType

字 段 的 ODBC C 数 据 类 型 。 缺 省 值 DEFAULT_FIELD_TYPE 强 迫GetFieldValue 根 据 下 面 的 表 格 确 定 与 SQL 数 据 类 型 相 对 应 的 C 数 据 类型 。或 者 , 你 可 以 直 接 指 定 数 据 类 型 或 选 择 一 个 兼 容 的 数 据 类 型 ; 例 如 ,

你 可 以 将 任 何 数 据 类 型 保 存 到 SQL_C_CHAR 中。

C 数 据 类 型 SQL 数 据 类 型

SQL_C_BIT SQL_BIT SQL_C_UTINYINT SQL_TINYINT SQL_C_SSHORT SQL_SMALLINT SQL_C_SLONG SQL_INTEGER

SQL_C_FLOAT SQL_REAL SQL_C_DOUBLE SQL_FLOAT

SQL_DOUBLE SQL_C_TIMESTAMP SQL_DATE

SQL_TIME SQL_TIMESTAMP

SQL_C_CHAR SQL_NUMERIC SQL_DECIMAL

续 表

SQL_BIGINT SQL_CHAR SQL_VARCHAR SQL_LONGVARCHAR

SQL_C_BINARY SQL_BINARY

SQL_VARBINARY SQL_LONGVARBINARY

有 关 ODBC 数 据 类 型 的 更 多 信 息 , 参 见 “ ODBC SDK 程 序 员 参 考 ” 的 附 录 D

中 的 “ S Q L 数 据 类 型 ” 和 “ C 数 据 类 型 ” 。

nIndex

字 段 从 零 开 始 的 索 引 。

strValue

一 个 指 向 CString 对 象 的 引 用 , 该 对 象 将 把 字 段 的 值 保 存 为 文 本 , 而 不 管字 段 的 数 据 类 型 。

说 明

此 成 员 函 数 用 来 获 取 当 前 记 录 中 的 字 段 数 据 。 你 可 以 用 名 字 或 者 索 引 来 查 找 一个 字 段 。 也 可 以 把 字 段 值 保 存 在 一 个 CDBVariant 对 象 或 一 个 CString 对 象 中 。

如 果 你 已 经 实 现 了 成 组 行 读 取 , 则 在 一 个 行 集 中 的 当 前 记 录 总 是 被 定 位 在 第 一个 记 录 。 要 在 一 个 给 定 的 行 集 中 对 一 个 记 录 使 用 GetFieldValue, 必 须 首 先 调 用SetRowsetCursorPosition 成 员 函 数 来 将 游 标 移 动 到 行 集 中 所 希 望 的 行 上 。 然 后为 这 一 行 调 用 GetFieldValue 。 要 实 现 成 组 行 读 取 , 你 必 须 指 定 Open 成 员 函 数中 的 dwOptions 参 数 的 CRecordset::useMultiRow- Fetch 选 项 。

你 可 以 使 用 GetFieldValue 在 运 行 时 动 态 地 读 取 字 段 , 而 不 是 在 设 计 时 静 态 地 装订 它 们 。 例 如 , 如 果 你 已 经 直 接 从 CRecordset 声 明 了 一 个 记 录 集 对 象 , 你 就 必须 使 用 GetFieldValue 来 获 取 字 段 数 据 ; 记 录 字 段 交 换 ( RFX ) , 或 者 是 成 组 记

注 意 如 果 你 声 明 了 一 个 记 录 集 对 象 , 而 不 是 从 CRecordset 派 生 , 则 不被 装 载 ODBC 游 标 库 。 此 游 标 库 要 求 记 录 集 至 少 有 一 个 边 界 列 ; 但 是 , 当你 直 接 使 用 CRecordset 时 , 没 有 一 个 列 是 边 界 。 成 员 函 数CDatabase::OpenEx 和 CDatabase::Open 控 制 游 标 库 是 否 被 装 载 。

GetFieldValue 调 用 ODBC API 函 数 SQLGetData 。 如 果 你 的 驱 动 器 为 字 段 值 的实 际 长 度 输 出 值 SQL_NO_TOTAL , GetFieldValue 抛 出 一 个 异 常 。 关 于SQLGetData 的 更 多 消 息 , 参 见 “ ODBC SDK 程 序 员 参 考 ” 。

示 例

下 面 的 例 子 代 码 说 明 如 何 为 一 个 直 接 从 CRecordset 声 明 的 记 录 集 对 象 调 用

GetFieldValue 。

// 不 要 装 载 游 标 库

CDatabase db;

db.OpenEx( NULL, CDatabase::forceOdbcDialog );

// 直 接 从 CRecordset 创 建 并 打 开 一 个 记 录 集 对 象 。

// 注 意 在 一 个 被 连 接 的 数 据 库 中 必 须 存 在 一 个 表 。

// 使 用 仅 向 前 类 型 的 记 录 集 以 获 得 最 佳 的 性 能 , 因 为 值 需 要 MoveNext 函 数 。

CRecordset rs( &db );

rs.Open( CRecordset::forwardOnly,

_T( "SELECT * FROM SomeTable" ) );

// 创 建 一 个 CDBVariant 对 象 来 保 存 字 段 数 据

CDBVariant varValue;

// 在 记 录 集 中 循 环 , 使 用 GetFieldValue 和 GetODBCFieldCount 来 获 取 所 有 列

中 的 数 据

short nFields = rs.GetODBCFieldCount( ); while( !rs.IsEOF( ) )

{

for( short index = 0; index < nFields; index++ )

{

rs.GetFieldValue( index, varValue );

// 对 varValue 作 某 些 操 作 。

}

rs.MoveNext( );

}

rs.Close( );

db.Close( );

注 意 与 DAO 类 CDaoRecordset 不 一 样 ,CRecordset 没 有 SetFieldValue 成 员 函 数 。 如 果 你 直 接 从 CRecordset 创 建 了 一 个 对 象 , 它 实 际 上 是 只 读的 。

请 参 阅 CRecordset::DoFieldExchange, CRecordset::DoBulkFieldExchange,

CRecordset::GetODBCFieldCount, CRecordset::GetODBCFieldInfo, CRecordset::SetRowsetCursorPosition

CRecordset::GetODBCFieldCount

short GetODBCFieldCount() const;

返 回 值

数 据 集 中 的 字 段 数 。

说 明

此 成 员 函 数 用 来 获 取 记 录 集 中 的 字 段 总 数 。

请 参 阅 CRecordset::GetFieldValue

CRecordset::GetODBCFieldInfo

void GetODBCFieldInfo( LPCTSTR lpszNam e, CODBCFieldInfo& fieldinfo ); throw( CDBException );

void GetODBCFieldInfo( short nIndex , CODBCFieldInfo& fieldinfo );

throw( CDBException );

参 数

lpszName

字 段 的 名 字 。

fieldinfo

一 个 指 向 CODBCFieldInfo 结 构 的 引 用 。

nIndex

字 段 从 零 开 始 的 索 引 。

说 明

此 成 员 函 数 用 来 获 取 记 录 集 中 的 字 段 的 信 息 。 此 函 数 的 一 个 版 本 可 以 让 你 用 名字 来 查 找 一 个 字 段 。 另 一 个 版 本 让 你 用 索 引 来 查 找 一 个 字 段 。

有 关 返 回 信 息 的 描 述 , 参 见 CODBCFieldInfo 结 构 。

请 参 阅 CRecordset::GetFieldValue, CODBCFieldInfo

CRecordset::GetRecordCount

long GetRecordCount() const;

返 回 值

记 录 集 中 记 录 的 数 目 。 如 果 记 录 集 中 不 包 含 记 录 , 则 为 0 , 如 果 不 能 确 定 记 录的 个 数 , 则 为 - 1 。

说 明

调 用 这 个 函 数 以 确 定 记 录 集 的 大 小 。

警 告 记 录 计 数 保 持 为 “ 顶 点 标 记 ” – – – – 当 用 户 移 动 记 录 时 可 以 看 见 的最 高 编 号 的 记 录 。 记 录 总 数 仅 在 用 户 已 经 移 动 过 最 后 一 个 记 录 时 才 可 知 。

由 于 性 能 原 因 , 在 应 用 程 序 中 调 用 MoveLast 时 , 记 录 计 数 不 被 更 新 。 要想 自 己 更 新 计 数 记 录 , 可 重 复 调 用 MoveNext 函 数 , 直 到 IsEOF 返 回 一 个非 零 值 。 通 过 CRecordset:AddNew 来 加 入 一 个 新 的 记 录 , 并 用 Update 来增 加 计 数 。 通 过 CRecordset:Delete 来 删 除 一 个 记 录 并 减 小 计 数 。

请 参 阅 CRec ordset::MoveLast, CRecordset::MoveNext, CRecordset::IsEOF, CRecordset::GetStatus

CRecordset::GetRowsetSize DWORD GetRowsetSize() const; 返 回 值

返 回 在 一 次 给 定 的 检 取 操 作 中 所 获 取 的 行 数 。

此 成 员 函 数 用 来 获 取 关 于 你 希 望 在 一 次 给 定 的 检 取 操 作 中 获 取 的 行 数 的 设 置 。如 果 你 使 用 成 组 行 检 取 , 记 录 集 被 打 开 时 的 缺 省 行 集 大 小 为 25 ; 否 则 为 1 。

为 了 实 现 成 组 行 检 取 , 你 必 须 在 Open 成 员 函 数 的 dwOptions 参 数 中 指 定CRecordset::use- MultiRowFetch 选 项 。 如 果 要 改 变 关 于 行 集 大 小 的 设 置 , 调 用SetRowsetSize 。

请 参 阅 CRecordset::Open, CRecordset::SetRowsetSize,

CRecordset::CheckRowsetError,

CRecordset::DoBulkFieldExchange

CRecordset::GetRowsFetched

DWORD GetRowsFetched( ) const;

在 执 行 了 指 定 的 检 取 操 作 后 从 数 据 源 获 取 的 行 数 。

说 明

调 用 这 个 成 员 函 数 以 确 定 在 检 取 后 实 际 获 得 了 多 少 记 录 。 当 你 实 现 成 组 行 检 取的 时 候 , 这 是 非 常 有 用 的 。 行 集 大 小 通 常 指 定 了 在 一 次 检 取 中 会 获 得 多 少 行 记录 , 但 是 , 记 录 集 中 记 录 的 总 数 也 会 影 响 能 在 行 集 中 获 取 的 行 数 。 例 如 , 如 果你 的 记 录 集 中 有 10 条 记 录 , 行 集 大 小 被 设 为 4 , 那 么 在 记 录 集 中 循 环 调 用MoveNext 会 导 致 最 后 一 个 行 集 中 只 有 2 条 记 录 。

为 了 实 现 成 组 行 检 取 , 你 必 须 在 Open 成 员 函 数 的 dwOptions 参 数 中 指 定CRecordset::use MultiRowFetch 选 项 。如 果 要 指 定 行 集 大 小 ,调用 SetRowsetSize 。示 例

MultiRowSet rs;

// 设 置 行 集 大 小

rs.SetRowsetSize( 5 );

// 打 开 记 录 集

rs.Open( CRecordset::dynaset, NULL, CRecordset::useMultiRowFetch );

// 在 记 录 集 中 循 环

while( !rs.IsEOF( ) )

{

for( int rowCount = 0;

rowCount < (int)rs.GetRowsFetched( ); rowCount++ )

{

// 作 某 些 操 作

}

rs.MoveNext( );

}

rs.Close( );

请 参 阅 CRecordset::SetRowsetSize, CRecordset::CheckRowsetError

CRecordset::GetRowStatus

WORD GetRowStatus(WORD wRow ) const;

返 回 值

行 的 状 态 值 。 有 关 细 节 参 见 说 明 部 分 。

参 数

wRow

该 行 在 记 录 集 中 的 位 置 , 从 1 开 始 计 算 。 这 个 值 的 范 围 是 从 1 到 行 集 的 大

小 。

说 明

调 用 这 个 函 数 以 获 得 当 前 行 集 中 某 行 的 状 态 。 GetRowStauts 返 回 一 个 值 , 指 明了 自 最 近 一 次 从 数 据 源 中 获 取 数 据 以 来 , 行 的 状 态 是 否 有 了 变 化 , 或 者 指 明 没

有 检 取 到 与 wRow 对 应 的 记 录 。 下 面 的 表 格 列 出 了 可 能 的 返 回 值 。

状 态 值 描 述

SQL_ROW_SUCCESS 该 行 没 有 发 生 变 化SQL_ROW_UPDATED 该 行 已 经 被 更 新SQL_ROW_DELETED 该 行 已 经 被 删 除SQL_ROW_ADDED 该 行 已 经 被 加 入SQL_ROW_ERROR 由 于 发 生 了 错 误 , 无 法 获 得 该 行SQL_ROW_NOROW 没 有 与 wRow 对 应 的 行

更 多 的 信 息 参 见 “ ODBC SDK 程 序 员 参 考 ” 中 的 ODBC API 函 数

SQLExtendedFetch 。

请 参 阅 CRecordset::CheckRowsetError, CRecordset::GetRowsFetched, CRecordset::RefreshRowset

CRecordset::GetStatus

void GetStatus( CRecordsetStatus& rStatus ) const;

参 数

rStatus

对 一 个 CRecordsetStatus 对 象 的 引 用 。 更 多 的 信 息 参 见 说 明 部 分 。

说 明

调 用 这 个 函 数 以 确 定 记 录 集 中 的 当 前 记 录 的 索 引 , 并 ( 或 ) 确 定 是 否 已 看 见 最后 一 个 记 录 。 CRecordset 试 图 跟 踪 索 引 , 但 是 在 某 些 情 况 下 可 能 无 法 做 到 。 有关 解 释 参 见 GetRecordCount 函 数 。

CRecordsetStatus 结 构 具 有 如 下 形 式 :

struct CRecordsetStatus

{

long m_lCurrentRecord; BOOL m_bRecordCountFinal;

};

CRecordsetStatus 的 两 个 成 员 的 含 义 如 下 :

  • m_lCurrentRecord 包 含 了 记 录 集 中 当 前 记 录 的 索 引 ( 从 零

    开 始 ) , 如 果 可知 的 话 。 如 果 不 能 确 定 索 引 , 则 该 成 员 中 包 含AFX_CURRENT_RECORD_UNDEFINED ( -2 )。如果 IsBOF 为 TRU E(空记 录 集 或 试 图 滚 动 到 第 一 个 记 录 之 前 ) , m_lCurrentRecord 将 被 设 为AFX_CURRENT_RECORD_BOF ( - 1 ) 。 如 果 是 在 第 一 个 记 录 , 它 被 设为 0 , 第 二 个 记 录 被 设 为 1 , 等 等 。

  • m_bRecordCountFinal 如 果 记 录 集 中 记 录 的 总 数 已 经 确 定 ,

    则 为 非 零 值 。通 常 这 个 必 须 通 过 在 记 录 集 头 开 始 并 调 用 M oveNex t, 直 到 IsEOF 返 回 非 零值 。 如 果 这 个 成 员 为 0 , 则 该 记 录 计 数 就 是 GetRecordCount 返 回 的 值 , 如

果 不 是 -1 , 就 只 是 记 录 的 “ 顶 点 标 记 ” 计 数 。

请 参 阅 CRecordset::GetRecordCount

CRecordset::GetSQL

const CString& GetSQL( ) const;

返 回 值

对 包 含 了 SQL 语 句 的 CSting 的 const 引 用 。

说 明

调 用 这 个 成 员 函 数 以 获 取 SQL 语 句 , 该 语 句 用 于 在 记 录 集 打 开 时 选 择 记 录 集 中的 记 录 。 这 通 常 是 一 个 SQL SELECT 语 句 。由 GetSQL 返 回 的 字 符 串 是 只 读 的 。

由 GetSQL 返 回 的 字 符 串 通 常 与 你 在 Open 成 员 函 数 的 lpszSQL 参 数 中 传 递 给 记

录 集 的 字 符 串 不 同 。 这 是 因 为 记 录 集 根 据 你 传 递 给 Open 的 选 项 、 通 过ClassWizard 指 定 的 选 项 、 在 m_strFilter 和 m_strSort 数 据 成 员 中 指 定 的 选 项 以及 指 定 的 其 它 任 何 参 数 来 构 造 一 个 完 整 的 SQL 语 句 。

重 点 在 调 用 Open 以 后 调 用 这 个 成 员 函 数 。

请 参 阅 CRecordset::GetDefaultSQL, CRecordset::Open, CRecordset::m_strFilter, CRecordset::m_strSort

CRecordset::GetTableName

const CString& GetTableName( ) const;

返 回 值

如 果 记 录 集 是 基 于 一 个 表 格 的 ,则 返 回 值 为 对 包 含 了 表 格 名 字 的 CString 的 const

引 用 。 否 则 是 一 个 空 字 符 串 。

调 用 这 个 函 数 以 获 取 SQL 表 的 名 字 , 记 录 集 查 询 是 基 于 这 个 表 的 。 只 有 当 记 录集 是 基 于 一 个 表 , 而 不 是 多 个 表 的 连 接 或 者 预 定 义 的 查 询 ( 存 储 过 程 ) 时 , GetTableName 才 是 有 效 的 。 这 个 表 名 是 只 读 的 。

重 点 在 调 用 了 Open 以 后 调 用 这 个 成 员 函 数 。

CRecordset::IsBOF BOOL IsBOF( ) const; 返 回 值

如 果 记 录 集 不 包 含 记 录 或 者 程 序 已 经 向 后 滚 动 到 第 一 个 记 录 之 前 , 则 返 回 一 个非 零 值 ; 否 则 返 回 值 为 0 。

在 记 录 之 间 滚 动 之 前 调 用 这 个 函 数 , 以 确 定 是 否 已 经 到 了 记 录 集 的 第 一 条 记 录之 前 。 你 也 可 以 与 IsEOF 一 起 使 用 IsBOF 函 数 来 确 定 记 录 集 中 是 否 包 含 记 录 , 或 者 为 空 。 在 调 用 Open 之 后 , 如 果 记 录 集 不 包 含 记 录 , IsBOF 返 回 非 零 值 。当 你 打 开 一 个 至 少 具 有 一 条 记 录 的 记 录 集 时 , 第 一 个 记 录 成 为 当 前 记 录 , IsBOF 返 回 0 。

如 果 当 前 记 录 为 第 一 条 记 录 并 且 你 调 用 了 MovePrev , IsBOF 将 随 后 返 回 一 个 非零 值 。 如 果 IsBOF 返 回 非 零 值 并 且 你 调 用 了 MovePrev , 将 会 发 生 错 误 。 如 果IsBOF 返 回 非 零 值 , 则 当 前 记 录 没 有 定 义 , 所 有 需 要 当 前 记 录 的 操 作 将 会 导 致错 误 。

这 个 例 子 在 双 向 滚 动 记 录 集 时 使 用 IsBOF 和 IsEOF 来 检 测 记 录 集 的 界 限 。

// 打 开 一 个 记 录 集 , 第 一 条 记 录 是 当 前 记 录 。

CCustSet rsCustSet( NULL ); rsCustSet.Open( );

if( rsCustSet.IsBOF( ) ) return;

// 记 录 集 为 空 。

// 滚 动 到 记 录 集 的 尾 部 , 越 过 最 后 一 条 记 录 ,

// 因 此 没 有 当 前 记 录 。

while ( !rsCustSet.IsEOF( ) ) rsCustSet. MoveNext( );

// 移 动 到 最 后 一 条 记 录

rsCustSet.MoveLast( );

// 滚 动 到 记 录 集 的 头 部 , 在 第 一 条 记 录 之 前 ,

// 因 此 没 有 当 前 记 录 。

while( !rsCustSet.IsBOF( ) ) rsCustSet. MovePrev( );

// 第 一 条 记 录 又 成 了 当 前 记 录 。

rsCustSet.MoveFirst( );

请 参 阅 CRecordset::IsEOF, CRecordset::MoveFirst, CRecordset::MovePrev

CRecordset::IsDeleted BOOL IsDeleted( ) const; 返 回 值

如 果 记 录 集 被 定 位 在 一 个 被 删 除 的 记 录 上 则 返 回 非 零 值 ; 否 则 返 回 0 。

说 明

调 用 这 个 函 数 以 确 定 当 前 记 录 是 否 已 被 删 除 。如 果 你 滚 动 到 一 条 记 录 ,IsDeleted 返 回 TRU E ( 非 零 值 ) , 在 你 能 够 执 行 任 何 记 录 集 操 作 之 前 , 你 必 须 先 滚 动 到其 它 记 录 。

注 意 IsDeleted 的 结 构 依 赖 于 许 多 因 素 , 例 如 你 的 记 录 集 的 类 型 , 记 录 集 是 否 可更 新 , 在 打 开 记 录 集 时 是 否 指 定 了 CRecordset::skipDeletedRecords 选 项 , 驱 动程 序 是 否 压 缩 被 删 除 的 记 录 , 以 及 是 否 有 多 个 用 户 。

有 关 CRecordset::skipDeletedRecords 和 驱 动 程 序 压 缩 的 更 多 信 息 参 见 Open 成员 函 数 。

注 意 如 果 你 实 现 了 成 组 行 读 取 , 你 不 能 调 用 IsDeleted , 而 应 该 调 用GetRowStatus 成 员 函 数 。

请 参 阅 CRecordset::Delete, CRecordset::IsBOF, CRecordset::IsEOF

CRecordset::IsEOF BOOL IsEOF( ) const; 返 回 值

如 果 记 录 集 中 不 包 含 记 录 或 者 程 序 已 经 滚 动 到 最 后 一 个 记 录 之 后 , 则 返 回 非 零值 ; 否 则 返 回 0 。

说 明

当 应 用 程 序 在 记 录 之 间 滚 动 时 , 调 用 这 个 成 员 函 数 来 确 定 应 用 程 序 是 否 已 滚 动超 出 了 记 录 集 的 最 后 一 个 记 录 。 你 也 可 以 使 用 IsEOF 来 确 定 记 录 集 中 是 包 含 了记 录 还 是 为 空 。 在 调 用 了 Open 以 后 , 如 果 记 录 集 不 包 含 记 录 , IsEOF 返 回 非

零 值 。 当 你 打 开 一 个 至 少 具 有 一 条 记 录 的 记 录 集 的 时 候 , 第 一 条 记 录 成 为 当 前记 录 , IsEOF 返 回 0 。

如 果 在 你 调 用 MoveNext 的 时 候 , 当 前 记 录 是 最 后 一 条 记 录 , IsEOF 将 会 返 回一 个 非 零 值 。 如 果 IsEOF 返 回 非 零 值 并 且 你 调 用 了 MoveNext , 将 会 产 生 一 个错 误 。 如 果 IsEOF 返 回 非 零 值 , 则 当 前 记 录 未 定 义 , 并 且 任 何 需 要 当 前 记 录 的操 作 将 会 导 致 错 误 。

示 例

参 见 IsBOF 的 例 子 。

请 参 阅 CRecordset::IsBOF, CRecordset::MoveLast, CRecordset::MoveNext

CRecordset::IsFieldDirty

BOOL IsFieldDirty( void* pv ); throw( CMemoryException );

返 回 值

如 果 由 于 调 用 了 AddNew 或 Edit , 指 定 的 字 段 数 据 成 员 被 改 变 了 , 则 返 回 非 零值 ; 否 则 返 回 0 。

参 数

pv

指 向 想 要 检 查 其 状 态 的 字 段 数 据 成 员 的 指 针 ; 或 者 为 NULL , 用 来 确 定某 些 字 段 是 否 被 更 改 了 。

说 明

调 用 这 个 成 员 函 数 以 确 定 指 定 的 字 段 数 据 成 员 是 否 因 为 调 用 了 Edit 或 AddNew 而 改 变 。 当 调 用 CRecordset 的 Update 成 员 函 数 ( 跟 在 Edit 或 AddNew 调 用 之后 ) 更 新 当 前 记 录 时 , 所 有 被 修 改 了 的 字 段 数 据 成 员 中 的 数 据 都 将 被 传 送 给 数据 源 上 的 对 应 记 录 。

注 意 这 个 成 员 函 数 对 使 用 了 成 组 行 检 取 的 记 录 集 不 起 作 用 。 如 果 你 实现 了 成 组 行 检 取 , 那 么 IsFieldDirty 将 总 是 返 回 FALSE 并 导 致 一 个 失 败的 断 言 。

调 用 IsFieldDirty 之 后 , 前 面 调 用 SetFieldDirty 的 效 果 将 会 被 复 位 , 因 为 字 段 的状 态 将 被 重 新 计 算 。 在 使 用 AddNew 的 时 候 , 如 果 当 前 字 段 值 与 null 值 不 同 , 字 段 状 态 将 被 设 为 改 变 过 的 。 在 使 用 Edit 的 时 候 , 如 果 字 段 值 与 缓 冲 的 值 不 同 ,

则 字 段 状 态 被 设 为 改 变 过 的 。

IsFieldDirty 是 通 过 DoFieldExchange 实 现 的 。

请 参 阅 CRecordset::SetFieldDirty, CRecordset::IsFieldNull

CRecordset::IsFieldNull

BOOL IsFieldNull( void* pv ); throw( CMemoryException );

返 回 值

如 果 指 定 的 字 段 数 据 成 员 被 标 记 为 Null, 则 返 回 一 个 非 零 值 ; 否 则 返 回 0 。

参 数

pv

指 向 一 个 要 检 查 其 状 态 的 字 段 数 据 成 员 的 指 针 , 或 者 是 NULL , 以 确 定

是 否 所 有 的 字 段 都 是 Null。

说 明

调 用 这 个 成 员 函 数 以 确 定 记 录 集 中 指 定 的 字 段 数 据 成 员 是 否 被 标 记 为 Null 。( 在数 据 库 术 语 中 , Null 表 示 “ 没 有 值 ” , 与 C++ 中 的 NULL 不 同 ) 如 果 一 个 字 段数 据 成 员 被 标 记 为 Null , 它 可 以 解 释 为 当 前 记 录 的 某 一 列 没 有 值 。

注 意 这 个 成 员 函 数 对 使 用 了 成 组 行 检 取 的 记 录 集 不 起 作 用 。 如 果 你 实现 了 成 组 行 检 取 , IsFieldNull 将 总 是 返 回 FALSE , 并 将 导 致 断 言 失 败 。

IsFieldNull 是 通 过 DoFieldExchange 实 现 的 。

请 参 阅 CRecordset::SetFieldNull, CRecordset::IsFieldDirty

CRecordset::IsFieldNullable

BOOL IsFieldNullable( void* pv ); throw( CDBException )

参 数

pv

指 向 要 检 查 其 状 态 的 字 段 数 据 成 员 的 指 针 。 或 者 是 NULL , 表 示 要 确 定是 否 所 有 的 字 段 都 可 以 被 设 置 为 Null 值 。

说 明

调 用 这 个 函 数 以 确 定 指 定 的 字 段 数 据 成 员 是 否 可 以 为 空 ( 可 以 被 设 为 Null 值 ,

C++ 的 NULL 与 数 据 库 术 语 中 的 Null 并 不 相 同 , 后 者 意 味 着 “ 没 有 值 ” ) 。

注 意 如 果 你 实 现 了 成 组 行 检 取 , 你 不 能 调 用 IsFieldNullable , 而 是 应

当 调 用 GetODBCFieldInfo 成 员 函 数 以 确 定 一 个 字 段 是 否 可 以 被 设 为 Null 值 。 注 意 你 在 任 何 时 候 都 可 以 调 用 GetODBCFieldInfo , 而 不 用 考 虑 你 是否 实 现 了 成 组 行 检 取 。

不 能 为 空 的 字 段 必 须 具 有 值 。 如 果 你 试 图 在 增 加 或 更 新 一 个 记 录 时 将 这 样 一 个字 段 的 值 设 置 为 Null, 则 数 据 源 将 拒 绝 增 加 或 更 新 , 并 且 Update 将 抛 出 一 个异 常 。 异 常 发 生 在 调 用 Update 时 , 而 不 是 发 生 在 调 用 SetFieldNull 时 。

用 NULL 作 为 IsFieldNullable 函 数 的 第 一 个 参 数 , 将 使 该 函 数 只 应 用 于

outputCloumn s, 而 不 作 用 于 param s。 例 如 , 调 用

SetFieldNull( NULL );

这 只 将 设 置 outputColumns 为 NULL ,而 Params 将 不 受 影 响 。

要 作 用 于 param s, 你 必 须 为 所 想 要 设 置 的 各 个 params 提 供 实 际 地 址 , 例 如 :

SetFieldNull( &m_strParam );

这 意 味 着 应 用 程 序 不 能 像 对 outputColumns 一 样 , 将 所 有 params 都 设 置 为

NULL 。

IsFieldNullable 通 过 DoFieldExchange 实 现 。

请 参 阅 CRecordset::IsFieldNull, CRecordset::SetFieldNull

CRecordset:: IsOpen BOOL IsOpen() const; 返 回 值

如 果 先 前 已 经 调 用 了 记 录 集 对 象 的 Open 或 Requery 成 员 函 数 , 并 且 记 录 集 还未 关 闭 , 则 返 回 一 个 非 零 值 , 否 则 返 回 值 为 零 。

此 成 员 函 数 用 来 确 定 记 录 集 是 否 已 经 打 开 。

CRecordset::Move

virtual void Move( long nRows , W O R D wFetchType = SQL_FETCH_RELATIVE ); throw( CDBException, CMemoryException );

参 数

nRows

要 向 前 或 向 后 移 动 的 行 数 。 正 值 表 示 向 前 移 动 , 直 至 移 动 到 记 录 集 的 尾部 。 负 值 表 示 向 后 移 动 , 直 至 移 动 到 开 始 处 。

wFetchType

确定 Move 将 要 获 取 的 行 集 。 其 细 节 参 见 说 明 部 分 。

此 成 员 函 数 用 来 在 记 录 集 中 向 前 或 向 后 移 动 当 前 记 录 指 针 。 如 果 你 给 nRows 传递 一 个 为 0 的 值 , 则 Move 刷 新 当 前 记 录 ; Move 将 终 止 当 前 的 AddNew 或 Edit 模 式 , 并 且 将 把 当 前 记 录 的 值 恢 复 到 调 用 AddNew 或 Edit 之 前 的 值 。

注 意 当 在 记 录 集 中 移 动 时 , 不 能 略 过 被 删 除 的 记 录 。 有 关 的 细 节 可 以参 见 IsDeleted 成 员 函 数 。

Move 用 行 集 来 定 位 记 录 集 。 根 据 传 递 给 nRowswFetchType 的 值 , Move 检取 相 应 的 行 集 , 然 后 将 此 行 集 中 的 第 一 个 记 录 作 为 当 前 记 录 。 如 果 你 还 没 有 实现 成 组 行 检 取 , 则 行 集 的 大 小 总 是 1 。 当 检 取 一 个 行 集 时 , Move 直 接 调 用CheckRowsetError 成 员 函 数 来 处 理 检 取 中 发 生 的 任 何 错 误 。

Move 与 其 他 的 C R ecordset 成 员 函 数 是 等 同 的 , 这 得 看 你 所 传 递 的 值 。 尤 其 是 ,

数 值 W F etchType 指 明 了 更 为 直 观 的 成 员 函 数 , 对 于 移 动 当 前 记 录 来 说 , 可 能更 喜 欢 使 用 该 方 法 。

下 面 的 表 列 出 了 wFetchType 可 能 的 取 值 , Move 根 据 wFectchTypenRows 将获 取 的 行 集 , 和 其 它 对 应 于 wFetchType 的 相 当 的 成 员 函 数 。

W fetchType 获取的行集 等效成员函数

SQL_FETCH_REL ATIVE SQL_FETCH_NEX T

S QL_FETCH_PRIO R SQL_FETCH_FIRS T

从 当 前 行 集 的 第 一 行 开 始 的 nRows 行 的行 集 , ( 缺 省 值 )

下 一 个 行 集 ; nRows 被 忽 略 MoveNext

前 一 个 行 集 ; nRows 被 忽 略 MovePrev

记 录 集 中 的 第 一 个 行 集 , nRows 被 忽 略 MoveFirst

SQL_FETCH_LAS T SQL_FETCH_ABS OLUTE

记 录 集 中 的 最 后 一 个 完 整 的 行 集 ; nRows

被 忽 略

如 果 nRows > 0 , 行 集 从 记 录 集 的 开 始 处开 始 nRows 行 。 如 果 nRows < 0 , 则 行 集从 记 录 集 的 结 尾 处 开 始 nRows 行 。 如 果nRows = 0 , 则 返 回 一 个 BOF 条件

续 表

MoveLast

SetAbsolut ePosition

SQL_FETCH_BOO K M A R K

行 集 开 始 于 书 签 值 与 nRows 一 致 的 行 SetBookm

ark

注 意 对 于 只 向 前 的 记 录 集 , Move 只 在 wFetchType 的 值 为SQL_FET C H_NEXT 才 有 效 。

警 告 如 果 记 录 集 没 有 记 录 则 调 用 Move 将 抛 出 一 个 异 常 。 要 确 定 记 录 集是 否 有 记 录 , 可 以 调 用 IsBOF 和 IsEOF 。

如 果 你 已 经 滚 动 过 了 记 录 集 的 开 始 或 结 尾 ( IsBOF 或 IsEOF 返 回 非 零 值 ) , 则调 用 Move 函 数 将 有 可 能 抛 出 一 个 CDBException 。 例 如 , 如 果 IsEOF 返 回 非 零

不 会 抛 出 异 常 。

如 果 你 在 当 前 记 录 被 更 新 或 增 加 时 调 用 M ove , 则 更 新 的 值 将 丢 失 , 并 且 不 会给 出 警 告 。

有 关 的 信 息 , 参 见 “ ODBC SDK 程 序 员 参 考 ” 中 的 ODBC API 函 数

SQLExtendedFetch 。

示 例

// rs 是 一 个 CRecordset 或 一 个 CRecordset 派 生 对 象 。

// 将 行 集 的 大 小 改 变 为 5 rs.SetRowsetSize( 5 );

// 移 动 到 记 录 集 中 的 第 一 个 记 录

rs.MoveFirst( );

rs.Move( 5 );

// 用 其 它 相 当 的 方 法 移 动 到 第 六 个 记 录

// rs.Move( 6, SQL_FETCH_ABSOLUTE );

// rs.SetAbsolutePosition( 6 );

// 在 这 种 情 况 下 , 第 六 个 记 录 是 下 一 个 行 集 的 第 一 个 记 录 。

// 所 以 下 面 的 方 法 也 是 相 当 的 。

// rs.Move( 1, SQL_FETCH_NEXT );

// rs.MoveNext( );

请 参 阅 CRecordset::MoveNext, CRecordset::MovePrev, CRecordset::MoveFirst,

CRecordset::MoveLast, CRecordset::SetAbsolutePosition, CRecordset::SetBookmark,

CRecordset::IsBOF, CRecordset::IsEOF, CRecordset::CheckRowsetError

CRecordset::MoveFirst

void MoveFirst();

throw(CDBException, CMemoryExc e ption );

说 明

此 成 员 函 数 用 来 使 第 一 个 行 集 中 的 第 一 个 记 录 成 为 当 前 记 录 。 不 管 是 否 实 现 了成 组 行 检 取 , 此 记 录 都 是 记 录 集 中 的 第 一 个 记 录 。

你 不 用 在 打 开 记 录 集 之 后 就 立 刻 调 用 MoveFirst。 在 打 开 记 录 集 的 时 候 , 第 一个 记 录 ( 如 果 有 的 话 ) 会 自 动 成 为 当 前 记 录 。

注 意 对 于 仅 向 前 的 记 录 集 来 说 , 此 成 员 函 数 是 无 效 的 。

注 意 当 在 一 个 记 录 集 中 移 动 时 ,删 除 的 记 录 不 能 被 忽 略 。参 见 IsDelete 成 员 函 数 可 以 获 得 有 关 的 细 节 。

警 告 如 果 记 录 集 没 有 记 录 , 则 调 用 任 何 Move 函 数 都 将 抛 出 一 个 异 常 。要 确 定 记 录 集 中 是 否 有 记 录 , 可 以 调 用 IsBOF 和 IsEOF 。

在 当 前 记 录 正 在 被 更 新 或 增 加 时 , 如 果 你 调 用 任 何 Move 函 数 , 则 更 新 将 丢 失 , 并 且 不 给 出 警 告 。

示 例

参 见 IsBOF 的 例 子 。

请 参 阅 CRecordset::Move, CRecordset::MoveLast, CRecordset::MoveNext, CRecordset::MovePrev, CRecordset::IsBOF, CRecordset::IsEOF

CRecordset::MoveLast

void MoveLast();

throw( CDBException, CMemoryException );

说 明

此 成 员 函 数 用 来 使 最 后 一 个 完 整 行 集 中 的 第 一 个 记 录 成 为 当 前 记 录 。 如 果 你 还

没 有 实 现 成 组 行 检 取 , 则 你 的 记 录 集 的 行 集 大 小 是 1 , 所 以 MoveLast 只 简 单 地移 动 到 记 录 集 中 的 最 后 一 个 记 录 。

注 意 对 于 仅 向 前 记 录 集 , 此 成 员 函 数 是 无 效 的 。

注 意 当 在 一 个 记 录 集 中 移 动 时 , 不 能 忽 略 被 删 除 的 记 录 。 参 见IsDeleted 成 员 函 数 会 获 得 有 关 的 细 节 。

警 告 如 果 记 录 集 没 有 记 录 , 则 调 用 任 何 Move 函 数 都 将 抛 出 一 个 异 常 。要 确 定 记 录 集 中 是 否 有 记 录 , 可 以 调 用 IsBOF 和 IsEOF 。

在 当 前 记 录 正 在 被 更 新 或 增 加 时 , 如 果 你 调 用 任 何 Move 函 数 , 则 更 新 将 丢 失 , 并 且 不 给 出 警 告 。

请 参 阅 CRecordset::Move, CRecordset::MoveFirst, CRecordset::MoveNext, CRecordset::MovePrev, CRecordset::IsBOF, CRecordset::IsEOF

CRecordset::MoveNext

void MoveNext();

throw ( CDBException, CMemoryException );

说 明

此 成 员 函 数 用 来 使 下 一 个 记 录 集 中 的 第 一 个 记 录 成 为 当 前 记 录 。 如 果 你 还 没 有实 现 成 组 行 检 取 , 则 你 的 记 录 集 的 行 集 的 大 小 为 1 , 所 以 MoveNext 只 简 单 地移 动 到 下 一 个 记 录 。

注 意 当 在 一 个 记 录 集 中 移 动 时 , 不 能 忽 略 被 删 除 的 记 录 。 参 见IsDeleted 成 员 函 数 会 获 得 有 关 的 细 节 。

警 告 如 果 记 录 集 没 有 记 录 , 则 调 用 任 何 Move 函 数 都 将 抛 出 一 个 异 常 。要 确 定 记 录 集 中 是 否 有 记 录 , 可 以 调 用 IsBOF 和 IsEOF 。

还 要 忠 告 你 , 必 须 在 调 用 MoveNext 之 前 调 用 IsEO F。 例 如 , 如 果 你 已 经 滚 动过 了 记 录 集 的 结 尾 , 则 IsEOF 将 返 回 非 零 值 ; 则 随 后 调 用 MoveNext 将 抛 出 一个 异 常 。

在 当 前 记 录 正 在 被 更 新 或 增 加 时 , 如 果 你 调 用 任 何 Move 函 数 , 则 更 新 将 丢 失 , 并 且 不 给 出 警 告 。

示 例

参 见 IsBOF 的 例 子 。

请 参 阅 CRecordset::Move, CRecordset::MovePrev, CRecordset::MoveFirst, CRecordset::MoveLast, CRecordset::IsBOF, CRecordset::IsEOF

CRecordset::MovePrev

void MovePrev();

throw( CDBException, CMemoryException );

说 明

此 成 员 函 数 用 来 使 上 一 个 记 录 集 中 的 第 一 个 记 录 成 为 当 前 记 录 。 如 果 你 还 没 有实 现 成 组 行 检 取 , 则 你 的 记 录 集 的 行 集 的 大 小 为 1 , 所 以 MovePrev 只 简 单 地移 动 到 前 一 个 记 录 。

注 意 此 成 员 函 数 对 于 只 向 前 记 录 集 无 效 。

注 意 当 在 一 个 记 录 集 中 移 动 时 ,不 能 忽 略 被 删 除 的 记 录 。参 见 IsDeleted 成 员 函 数 会 获 得 有 关 的 细 节 。

警 告 如 果 记 录 集 没 有 记 录 , 则 调 用 任 何 Move 函 数 都 将 抛 出 一 个 异 常 。要 确 定 记 录 集 中 是 否 有 记 录 , 可 以 调 用 IsBOF 和 IsEOF 。

还 要 忠 告 你 , 必 须 在 调 用 MovePrev 之 前 调 用 IsBO F。 例 如 , 如 果 你 已 经 滚 动

过 了 记 录 集 的 开 始 , 则 IsBOF 将 返 回 非 零 值 ; 则 随 后 调 用 MovePrev 将 抛 出 一个 异 常 。

在 当 前 记 录 正 在 被 更 新 或 增 加 时 , 如 果 你 调 用 任 何 Move 函 数 , 则 更 新 将 丢 失 , 并 且 不 给 出 警 告 。

示 例

参 见 IsBOF 的 例 子 。

请 参 阅 CRecordset::Move, CRecordset::MoveNext, CRecordset::MoveFirst, CRecordset::MoveLast, CRecordset::IsBOF, CRecordset::IsEOF

CRecordset::OnSetOptions

virtual void OnSetOptions( HSTMT hstmt );

参 数

hstmt

要 设 置 其 选 项 的 ODBC 语 句 的 HSTM T。

说 明

框 架 调 用 此 成 员 函 数 来 设 置 记 录 集 的 初 始 选 项 。 OnSetOption 确 定 数 据 源 是 否支 持 可 滚 动 游 标 和 游 标 并 行 特 性 , 并 相 应 设 置 记 录 集 的 选 项 。

可 以 重 载 OnSetOptions 函 数 来 设 置 专 用 于 驱 动 器 或 数 据 源 的 附 加 项 。 例 如 , 如果 数 据 源 支 持 打 开 进 行 独 占 存 取 , 则 应 用 程 序 可 以 重 载 OnSetOptions 来 利 用 这种 功 能 。

请 参 阅 CDatabase::OnSetOptions

CRecordset::Open

virtual BOOL Open( UINT nOpenType = AFX_DB_USE_DEFAULT_TYPE, LPCTSTR lpszSQL = NULL, DWORD dwOptions = none );

throw( CDBException, CMemoryException );

返 回 值

如 果 CRecordset 对 象 被 成 功 打 开 , 则 返 回 非 零 值 ; 否 则 , 如 果 CDatabase::Open

( 如 果 被 调 用 了 ) 返 回 0 , 则 返 回 0 。

参 数

nOpenType

接 收 缺 省 值 AFX_DB_USE_DEFAULT_TYPE , 或 使 用 下 列 enum OpenType 枚 举 值 之 一 :

  • CRecordset::dynaset 可 以 双 向 滚 动 的 记 录 集 。 当 记 录 集 被

    打 开 时 , 记

录 集 的 全 体 成 员 和 记 录 的 顺 序 都 被 确 定 , 但 是 伴 随 一 次 获 取 操 作 , 其它 用 户 对 数 据 值 所 做 的 改 变 是 可 见 的 。

  • CRecordset::snapshot 可 以 双 向 滚 动 的 静 态 记 录 集 。 当 记 录

    集 被 打 开时 , 记 录 集 的 全 体 成 员 和 记 录 的 顺 序 都 被 确 定 了 ; 当 记 录 被 获 取 时 , 其 数 据 值 是 确 定 的 。 其 它 用 户 在 记 录 集 被 关 闭 , 然 后 在 打 开 之 前 是 不可 见 的 。

  • CRecordset::dynamic 可 以 双 向 滚 动 的 记 录 集 。 伴 随 一 次 获

    取 操 作 , 其 它 用 户 对 成 员 ,顺 序 和 数 据 值 所 做 的 改 变 是 可 见 的 。注 意 ,许 多 ODBC 驱 动 器 是 不 支 持 这 种 类 型 的 记 录 集 的 。

  • CRecordset::forwardOnly 只 能 向 前 滚 动 的 只 读 的 记 录 集 。

对 于 CRecordset 来 说 , 缺 省 的 值 是 CRecordset::snapshot。 这 种 缺 省 值 机 制 , 允许 Visual C++ 向 导 与 具 有 不 同 缺 省 值 的 ODBC CRecordset 和 DAO

CD ao Recordset 进 行 交 互 。

与 此 有 关 的 信 息 , 参 见 “ ODBC SDK 程 序 员 参 考 ” 中 文 章 的 “ 使 用 块 和 可 滚 动游 标 ” 。

警 告 如 果 不 支 持 要 求 的 类 型 , 框 架 将 抛 出 一 个 异 常 。

lpszSQL

一 个 包 含 下 列 值 之 一 的 字 符 串 指 针 :

  • 一个 NULL 指 针 。

  • 一 个 表 名 。

  • 一条 SQL SELECT 语 句 ( 可 选 择 带 一 条 SQL WHERE 或 ORDER BY

子 句 ) 。

  • 一条 CALL 语 句 , 指 定 一 个 预 定 义 查 询 ( 存 储 过 程 ) 名

    。 注 意 , 你 不能 在 卷 括 号 和 CALL 关 键 字 之 间 插 入 空 格 。

有 关 这 个 字 符 串 的 更 多 信 息 , 请 参 见 说 明 下 的 表 , 以 及 对 ClassWizard 的 作 用的 讨 论 。

注 意 在 你 的 结 果 集 中 , 列 的 顺 序 必 须 与 在 你 的 重 载 的 DoFieldExchange 或 DoBulkFieldExchange 函 数 中 的 RFX 和 Bulk RFX 函 数 调 用 的 顺 序 相 匹配 。

dwOptions

一 个 bitmask , 它 可 以 指 定 下 列 值 的 组 合 。 这 些 值 中 的 某 些 是 相 互 独 立 的 。缺 省 的 值 是 none 。

  • CRecordset::none 未 设 置 选 项 。 此 参 数 值 与 所 有 其 它 的 值

    是 相 互 独 立的 。 缺 省 的 , 记 录 集 可 以 用 Edit 或 Delete 来 更 新 , 并 允 许 用 AddNew 来 添 加 新 记 录 。 这 种 可 更 新 性 依 赖 于 数 据 源 , 就 像 你 所 指 定 的nOpenType 选 项 。 成 组 添 加 的 优 化 是 没 有 用 的 。 成 组 行 检 取 不 会 被 实

现 。 在 记 录 集 中 导 航 时 , 不 能 略 过 被 删 除 的 记 录 。 书 签 是 没 有 用 的 。实 现 了 自 动 脏 字 段 检 查 。

  • CRecordset::appendOnly 不 允 许 在 记 录 集 中 进 行 Edit 或 Delete

    。 值 允许 AddNew 。 此 选 项 与 CRecordset::readOnly 相 互 独 立 。

  • CRecordset::readOnly 用 只 读 方 式 打 开 记 录 集 。 此 选 项 与

CRecordset::appendOnly 相 互 独 立 。

  • CRecordset::optimizeBulkAdd 使 用 预 备 的 S Q L 语 句 来 优 化 一

    次 添 加多 个 记 录 。 只 有 在 你 不 使 用 ODBC API 函 数 SQLSetPos 来 更 新 记 录 集时 才 使 用 。 第 一 次 更 新 确 定 将 哪 一 个 字 段 标 记 为 脏 的 。 此 选 项 与CRecordset::useMultiRowFetch 相 互 独 立 。

  • CRecordset::useMultiRowFetch 实 现 成 组 行 检 取 , 允 许 在 一 次

    检 取 操作 中 获 取 多 行 。 这 是 一 个 高 级 特 征 , 是 设 计 来 提 高 性 能 的 ; 但 是 ,

ClassWizard 不 支 持 成 组 记 录 字 段 交 互 。 此 选 项 与CRecordset::optimiazBulkAdd 相 互 独 立 。 注 意 , 如 果 你 指 定 了CRecordset::useMultiRowFetch , 则 选 项 CRecordset::noDirtyFieldCheck 将 自 动 被 返 回 ( 双 缓 冲 将 无 效 ) ; 对 于 只 向 前 记 录 集 , 选 项CRecordset::useExtendedFetch 将 被 自 动 返 回 。

  • CRecordset::skipDeletedRecords 当 在 记 录 集 中 导 航 时 , 略 过

    所 有 已 被删 除 的 记 录 。 这 将 使 某 个 相 关 获 取 的 性 能 下 降 。 在 一 个 只 向 前 的 记 录集 中 , 此 选 项 是 无 效 的 。 注 意 , CRecordset::skipDeletedRecords 与 “ 驱动 器 包 装 ” 相 似 , 驱 动 器 包 装 意 味 着 被 删 除 的 行 被 从 记 录 集 中 移 走 。但 是 , 如 果 你 的 驱 动 器 包 装 记 录 , 则 它 将 只 略 过 那 些 被 你 删 除 的 记 录 ; 而 不 会 略 过 在 记 录 集 打 开 时 被 其 它 用 户 删 除 的 记 录 。CRecordset::skipDeletedRecords 将 会 略 过 被 其 它 用 户 删 除 的 记 录 。

  • CRecordset::useBookarks 允 许 在 记 录 集 中 使 用 书 签 , 如 果 支

    持 书 签 的话 。 书 签 会 使 数 据 检 取 变 慢 , 但 是 会 提 高 数 据 导 航 的 性 能 。 在 只 向 前的 记 录 集 中 此 选 项 是 无 效 的 。

  • CRecordset::noDirtyFieldCheck 关 闭 自 动 脏 数 据 检 查 ( 双 缓 冲

    ) 。 这将 提 高 性 能 ; 但 是 , 你 必 须 通 过 调 用 SetFieldDirty 和 SetFieldNull 成 员函 数 来 手 动 标 记 变 脏 的 字 段 。 注 意 , CRecordset 类 中 的 双 缓 冲 类 似 于CDaoRecordset 中 的 双 缓 冲 。 但 是 , 在 CRecordset 中 , 你 不 能 在 独 立字 段 中 使 双 缓 冲 有 效 ; 你 只 能 对 所 有 字 段 使 它 有 效 或 无 效 。 注 意 , 如果 你 指 定 了 选 项 CRecordset::useMultiRowFetch , 则CRecordset::noDirtyFieldCheck 将 被 自 动 返 回 ; 但 是 , SetFieldDirty 和SetFieldNull 不 能 在 实 现 成 组 行 检 取 的 记 录 集 中 使 用 。

  • CRecordset::executeDirect 不 要 使 用 预 备 的 SQL 语 句 。 如 果 永

    远 不 会

调用 Requery 成 员 函 数 , 则 指 定 此 选 项 来 提 高 性 能 。

  • CRecordset::useExtendedFetch 实 现 SQLException 来 代 替 SQLFetch

    。这 是 设 计 来 在 只 向 前 的 记 录 集 中 实 现 成 组 行 检 取 的 。 如 果 你 在 一 个 只向 前 的 记 录 集 中 指 定 了 选 项 CRecordset::userMultiRowFetch , 则CRecordset::useExtendedFetch 将 被 自 动 返 回 。

  • CRecordset:: userAllocMultiRowBuffers 用 户 将 为 数 据 分 配 存 储

    缓 存 。如 果 你 想 分 配 自 己 的 存 储 区 , 将 此 选 项 用 与CRecordset::useMultiRowFetch 连 接 ; 否 则 , 框 架 将 自 动 分 配 必 要 的 存储 区 。 注 意 , 指 定 了 CRecordset::userAllocMutiRowBuffers , 而 没 有 指定 CRecordset::useMultiRowFetch , 将 导 致 一 个 失 败 断 言 。

说 明

你 必 须 调 用 此 成 员 函 数 来 运 行 记 录 集 定 义 的 查 询 。 在 调 用 Open 之 前 , 你 必 须构 造 记 录 集 对 象 。

此 记 录 集 与 数 据 源 的 连 接 依 赖 于 在 调 用 Open 之 前 你 是 如 何 构 造 这 个 记 录 集的 。 如 果 你 将 一 个 没 有 连 接 到 一 个 数 据 源 的 CDatabase 对 象 传 递 给 记 录 集 构 造函 数 , 此 成 员 函 数 使 用 GetDefaultConnect 来 尝 试 打 开 该 数 据 库 对 象 。 如 果 你 将NULL 传 递 给 记 录 集 构 造 函 数 , 则 此 成 员 函 数 为 你 构 造 一 个 CDatabase 对 象 , 并 且 Open 试 图 连 接 给 数 据 库 对 象 。 有 关 关 闭 记 录 集 和 在 这 些 不 同 的 环 境 下 的连 接 的 细 节 , 请 参 见 Close 。

注 意 通 过 一 个 CRecordset 对 象 对 数 据 源 的 访 问 总 是 被 共 享 的 。 不 像CDaoRecordset 类 , 不 能 使 用 一 个 CRecordset 对 象 来 打 开 一 个 具 有 独 占

访 问 的 数 据 源 。

当 你 调 用 Open 时 , 一 条 查 询 语 句 , 通 常 是 一 条 SQL SELECT 语 句 , 基 于 下 表给 出 的 标 准 来 选 择 记 录 :

lpszSQL 参 数 的 值 选 择 的 记 录 所 决 定 于 示例

NULL 由 GetDefaultSQL 返 回 的 字 符 串

S Q L 表 名 在 DoFieldExchange 或DoBulkFieldExchange 中 的 列 表的 所 有 列

“ Custome r”

预 定 义 的 查 询 ( 存储 过 程 ) 名 称

该 查 询 被 定 义 的 要 返 回 的 列 “ {call

OverDueAccts} ”

SELECT 列表 从 指 定 的 表 中 选 出 的 指 定 的 列 SELECT CustId, FROM 列 表 CustName FROM

Custome r”

警 告 注 意 , 在 SQL 字 符 串 中 , 你 不 能 插 入 额 外 的 空 格 。 例 如 , 如 果 你在 卷 括 号 和 CALL 关 键 字 之 间 插 入 了 空 格 , MFC 将 错 误 地 将 这 个 SQL 串 解释 为 一 个 表 名 , 并 将 它 合 并 到 SELECT 语 句 中 , 这 将 导 致 抛 出 一 个 异 常 。

类 似 地 , 如 果 使 用 输 出 参 数 的 预 定 义 查 询 没 有 在 卷 括 号 和 ‘ ? ’ 号 之 间 插入 空 格 , 则 也 会 导 致 抛 出 异 常 。 最 后 , 你 不 能 在 一 个 CALL 语 句 中 的 卷 括号 之 前 和 在 一 个 SELECT 语 句 中 的 SELECT 关 键 字 之 前 插 入 空 格 。

通 常 的 程 序 是 将 NULL 传 递 给 Open ;在 这 种 情 况 下 ,Open 调用 GetDefaultSQ L。如 果 你 正 在 使 用 一 个 CRecordset 派 生 类 , GetDefaultSQL 给 出 你 在 ClassWizard 中 指 定 的 表 名 。 你 可 以 代 替 在 lpszSQL 参 数 中 指 定 其 它 的 信 息 。

不 管 传 递 的 是 什 么 , Open 都 为 查 询 构 造 一 个 最 后 的 SQL 字 符 串 ( 该 字 符 串 可能 有 SQL WHERE 和 ORDER BY 子 串 添 加 在 你 传 递 的 lpszSQL 串 中 ) , 然 后执 行 这 个 查 询 。 你 可 以 在 调 用 Open 之 后 通 过 调 用 GetSQL 来 检 查 这 个 构 造 出来 的 字 符 串 。

记 录 集 类 的 字 段 数 据 成 员 与 所 选 择 数 据 的 列 相 关 联 。 如 果 有 记 录 被 返 回 , 则 第一 个 记 录 成 为 当 前 记 录 。

如 果 你 想 为 记 录 集 设 置 选 项 , 比 如 一 个 过 滤 器 或 排 序 , 则 应 在 构 造 了 此 记 录 集对 象 之 后 , 但 在 调 用 Open 之 前 指 定 这 些 选 项 。 如 果 你 要 在 记 录 集 被 打 开 之 后刷 新 记 录 集 中 的 记 录 , 可 以 调 用 Requery 。

示 例

下 面 的 代 码 例 子 说 明 了 Open 调 用 的 不 同 形 式 。

// rs 是 一 个 CRecordset 或 CRecordset 派 生 对 象

// 用 缺 省 的 S Q L 语 句 打 开 rs

// 实 现 书 签 , 并 关 闭 自 动 脏 数 据 检 查

rs.Open( CRecordset::snapshot, NULL, CRecordset::useBookmarks | CRecordset::noDirtyFieldCheck );

// 传 递 一 个 完 整 的 SELECT 语 句 并 打 开 作 为 一 个 动 态 集

rs.Open( CRecordset::dynaset,

_T( "Select L_Name from Customer" ) );

// 接 收 所 有 的 缺 省 值

rs.Open( );

请 参 阅 CRecordset::CRecordset, CRecordset::Close, CRecordset::GetDefaultSQL,

CRecordset::GetSQL, CRecordset::m_strFilter, CRecordset::m_strSort, CRecordset::Requery

CRecordset::RefreshRowset

void RefreshRowset( WORD wRow , W O R D wLockType = SQL_LOCK_NO_CHANGE );

参 数

wRow

在 当 前 行 集 中 一 行 的 从 1 开 始 的 位 置 。 这 个 值 的 范 围 可 以 是 零 到 此 行 集 的大 小 之 间 。

wLockType

一 个 值 , 表 明 在 行 被 刷 新 之 后 如 何 去 加 锁 这 个 行 。 有 关 的 细 节 可 参 见 说 明部 分 。

说 明

此 成 员 函 数 用 来 为 当 前 行 集 中 的 一 行 更 新 数 据 和 状 态 。 如 果 你 传 递 一 个 为 零 的值 给 wRow , 则 此 行 集 中 的 每 一 行 都 将 被 刷 新 。

要 使 用 RefreshRowse t,你 必 须 已 经 通 过 指 定 Open 成 员 函 数 中 的 CRecordset::use- MulitRowFetch 选 项 实 现 了 成 组 行 检 取 。

RefreshRowset 调 用 ODBC API 函 数 SQLSetPo s。 参 数 wLockType 指 定 在 执 行

SQLSetPos 之 后 此 行 的 加 锁 状 态 。 下 面 的 表 格 描 述 了 wLockType 可 能 的 取 值 。

W lockType 描 述

SQL_LOCK_NO_CHANGE

( 缺 省 值 )

驱 动 器 和 数 据 源 保 证 该 行 的 加 锁 或 解 锁 状态 与 调 用 RefreshRowset 之 前 一 致

SQL_LOCK_EXCLUSIVE 驱 动 器 或 数 据 源 各 自 独 立 的 加 锁 该 行 。 不

是 所 有 的 数 据 源 都 支 持 这 种 加 锁 类 型

SQL_LOCK_UNLOCK 驱 动 器 或 数 据 源 解 锁 此 行 。 不 是 所 有 的 数

据 源 都 支 持 这 种 加 锁 类 型

有 关 SQLSetPos 的 更 多 信 息 , 请 参 见 “ ODBC SDK 程 序 员 参 考 ” 。

请 参 阅 CRecordset::SetRowsetCursorPosition, CRecordset::SetRowsetSize

CRecordset::Requery

virtual BOOL Requery();

throw ( CDBException, CMemoryException );

返 回 值

如 果 记 录 集 重 建 成 功 则 返 回 非 零 值 ; 否 则 返 回 0 。

说 明

此 成 员 函 数 用 来 重 建 ( 刷 新 ) 一 个 记 录 集 。 如 果 有 记 录 返 回 , 则 第 一 个 记 录 成为 当 前 记 录 。

为 了 使 记 录 集 可 反 映 你 或 其 它 用 户 正 对 数 据 集 进 行 的 添 加 或 删 除 , 你 必 须 调 用Requery 函 数 来 重 建 记 录 集 。 如 果 记 录 集 是 一 个 动 态 集 , 则 它 将 自 动 反 映 你 或其 它 用 户 对 其 现 有 记 录 ( 而 非 所 添 加 的 记 录 ) 的 更 新 。 如 果 记 录 集 是 一 个 快 照 , 则 应 用 程 序 必 须 调 用 Requery 来 反 映 其 它 用 户 的 标 记 及 添 加 和 删 除 。

无 论 是 对 一 个 动 态 集 还 是 对 一 个 快 照 , 都 可 以 在 应 用 程 序 想 要 用 一 个 新 的 过 滤器 或 排 序 , 或 新 的 参 数 值 来 重 建 记 录 集 的 任 何 时 候 , 调 用 Requery 函 数 。 可 以在 调 用 Requery 之 前 , 通 过 赋 新 值 给 m_strFilter 和 m_strSort 成 员 来 设 置 新 的 过滤 器 或 排 序 特 征 ; 赋 新 值 给 参 数 数 据 成 员 来 设 置 新 的 参 数 。 如 果 过 滤 器 和 排 序

如 果 重 建 记 录 集 的 尝 试 失 败 , 则 记 录 集 被 关 闭 。 在 调 用 Requery 之 前 , 你 可 以通 过 调 用 CanRestart 成 员 函 数 来 确 定 记 录 集 是 否 可 被 重 新 查 询 。 CanRestart 不保 证 Requery 会 成 功 。

注 意 只 能 在 调 用 Open 之 后 调 用 Requery 函 数 。

示 例

此 示 例 重 建 一 个 记 录 集 , 使 其 采 用 另 一 种 不 同 的 排 列 顺 序 。

// CRecordset::Requery 示 例

CCustSet rsCustSet( NULL );

// 打 开 一 个 记 录 集

rsCustSet.Open( );

// 使 用 该 记 录 集 ...

rsCustSet.m_strSort = "District, Last_Name"; if( !rsCustSet.CanRestart( ) )

return; // 不 能 查 询

if( !rsCustSet.Requery( ) )

// 查 询 失 败 , 因 此 进 行 某 种 行 动

请 参 阅 CRecordset::CanRestart, CRecordset::m_strFilter, CRecordset::m_strSort

CRecordset::SetAbsolutePosition

void SetAbsolutePosition( long nRows );

throw( CDBException, CMemoryException );

参 数

nRows

此 记 录 集 中 的 当 前 记 录 的 从 一 开 始 的 顺 序 位 置 。

说 明

此 成 员 函 数 用 来 将 记 录 集 定 位 在 指 定 记 录 号 对 应 的 记 录 上 。 SetAbsolutePosition

根 据 这 个 顺 序 位 置 来 移 动 当 前 的 记 录 指 针 。

注 意 此 成 员 函 数 在 只 向 前 的 记 录 集 中 是 无 效 的 。

对 于 ODBC 记 录 集 , 一 个 为 1 的 绝 对 位 置 设 置 指 向 记 录 集 中 的 第 一 个 记 录 ; 设置 0 指 向 文 件 开 始 ( B O F ) 位 置 。

你 也 可 以 传 递 负 值 给 SetAbsolutePosition 。 在 这 种 情 况 下 , 记 录 集 的 位 置 是 从记 录 集 的 结 尾 开 始 计 算 的 。 例 如 , SetAsolutePosition(-1) 当 前 记 录 指 针 移 动 到 记录 集 中 的 最 后 一 个 记 录 上 。

注 意 绝 对 位 置 并 不 是 用 来 作 为 记 录 号 的 替 代 品 。 书 签 仍 然 是 用 来 保 持和 返 回 到 给 定 记 录 的 最 受 欢 迎 的 方 式 , 因 为 当 一 个 记 录 前 面 的 记 录 被 删

除 时 , 该 记 录 的 绝 对 位 置 就 改 变 了 。 另 外 , 如 果 记 录 集 被 再 次 重 建 , 你就 不 能 保 证 一 个 给 定 记 录 将 具 有 相 同 的 绝 对 位 置 , 因 为 在 记 录 集 中 单 个记 录 的 顺 序 是 不 被 保 证 的 , 除 非 该 记 录 集 是 用 一 个 使 用 ORDER BY 子 句 的SQL 语 句 创 建 的 。

请 参 阅 CRecordset::SetBookmark

CRecordset::SetBookmark

void SetBookmark( const CDBVariant& varBookmark ); throw( CDBException, CMemoryException );

参 数

varBookmark

一 个 指 向 CDBVariant 对 象 的 引 用 , 该 对 象 包 含 了 一 个 指 定 记 录 的 书 签 值 。

说 明

此 成 员 函 数 用 来 将 记 录 集 定 位 在 包 含 指 定 书 签 的 记 录 上 。 为 了 确 定 在 此 记 录 集中 是 否 支 持 书 签 , 可 以 调 用 CanBookmark 。 如 果 支 持 书 签 , 为 了 使 书 签 可 以 使用 ,你 必 须 设 置 Open 成 员 函 数 中 的 dwOptions 参 数 的 CRecordset::useBookmarks 选 项 。

注 意 如 果 书 签 不 被 支 持 或 不 能 使 用 , 调 用 SetBookmark 将 导 致 抛 出 一个 异 常 。 在 只 向 前 的 记 录 集 中 是 不 支 持 书 签 的 。

第 一 次 获 取 当 前 记 录 的 书 签 , 可 调 用 GetBookmark , 它 将 书 签 值 保 存 在 一 个

CDBVariant 对 象 中 , 用 保 存 的 书 签 值 调 用 SetBookmark 可 以 返 回 该 记 录 。

注 意 在 进 行 了 一 定 的 记 录 集 操 作 之 后 , 你 必 须 在 调 用 SetBookmark 之前 检 查 书 签 是 否 持 续 可 用 。 例 如 , 如 果 你 用 GetBookmark 获 取 一 个 书 签 ,

然 后 调 用 Requery , 则 该 书 签 也 许 已 经 不 再 有 效 了 。 调 用CD a base::GetBookmarkPersistence 来 检 查 你 是 否 能 够 安 全 地 调 用SetBookmark 。

请 参 阅 CRecordset::CanBookmark, CRecordset::GetBookmark, CRecordset::SetAbsolutePosition, CDatabase::GetBookmarkPersistence

CRecordset::SetFieldDirty

void SetFieldDirty( void* pv , BOOL bDirty = TRUE );

参 数

pv

指 向 记 录 集 中 一 字 段 数 据 成 员 的 地 址 ,或 为 NULL 。如 果 该 参 数 为 NULL , 则 标 记 记 录 集 中 所 有 字 段 数 据 成 员 。( C++ NULL 与 数 据 库 术 语 中 的 Null 不 相 同 , 后 者 表 示 “ 没 有 值 ” ) 。

bDirty

如 果 要 将 字 段 数 据 成 员 标 记 为 “ 脏 的 ” ( 被 修 改 了 ) , 则 设 置 此 参 数 为TRUE ; 否 则 如 果 要 将 字 段 数 据 成 员 标 记 为 “ 干 净 的 ” ( 未 被 修 改 过 ) , 则 设 置 此 参 数 为 FALSE 。

说 明

此 成 员 函 数 用 来 标 记 记 录 集 中 的 一 个 字 段 数 据 成 员 为 被 修 改 了 或 未 被 修 改 过 。标 记 字 段 为 未 被 修 改 过 , 可 以 确 保 该 字 段 不 被 更 新 , 并 产 生 较 少 的 S Q L 语 句 。

注 意 此 成 员 函 数 对 使 用 成 组 行 检 取 的 记 录 集 是 不 适 用 的 。 如 果 你 已 经实 现 了 成 组 行 检 取 , 则 SetFieldDirty 将 导 致 一 个 失 败 断 言 。

框 架 标 记 改 变 过 的 字 段 数 据 成 员 来 确 保 记 录 字 段 交 换 机 制 ( RFX ) 将 它 们 写 入数 据 源 中 对 应 的 记 录 中 。 改 变 一 个 字 段 的 值 通 常 自 动 地 将 该 自 动 设 置 为 被 修 改

了 , 因 此 应 用 程 序 本 身 很 少 有 必 要 调 用 SetFieldDirty 函 数 , 但 有 时 可 能 想 要 确保 记 录 的 列 显 式 地 被 更 新 或 插 入 , 而 不 管 自 动 数 据 成 员 中 是 什 么 值 。

重 点 只 能 在 调 用 Edit 或 AddNew 之 后 调 用 SetFieldDirty 函 数 。

使 用 NULL 作 为 SetFieldDirty 函 数 的 第 一 个 参 数 , 将 使 该 函 数 只 应 用 于

outputColumn s, 而 不 作 用 于 param s。 例 如 , 调 用

SetFieldNull( NULL );

将 只 设 置 outputColumns 为 NULL , 而 params 将 不 受 影 响 。

要 想 作 用 于 param s, 应 用 程 序 必 须 对 所 想 要 作 用 的 各 个 param 提 供 实 际 地 址 , 例 如 :

SetFieldNull( &m_strParam );

这 意 味 着 应 用 程 序 不 能 像 对 outputColmns 一 样 将 所 有 params 都 设 置 为 NULL 。

请 参 阅 CRecordset::IsFieldDirty, CRecordset::SetFieldNull, CRecordset::Edit,

CRecordset::Update

CRecordset::SetFieldNull

void SetFieldNull( void* pv , BOOL bNull = TRUE );

参 数

pv

指 向 记 录 集 中 一 字 段 数 据 成 员 的 地 址 ,或 为 NULL 。如 果 该 参 数 为 NULL , 则 标 记 记 录 集 中 所 有 字 段 数 据 成 员 。( C++ NULL 与 数 据 库 术 语 中 的 Null 不 相 同 , 后 者 表 示 “ 没 有 值 ” ) 。

bNull

如 果 要 将 此 字 段 数 据 成 员 标 记 为 没 有 值 ( Null ) , 则 设 置 该 参 数 为 一 个非 零 值 。 如 果 要 将 此 字 段 数 据 成 员 标 记 为 非 Null, 则 设 置 该 参 数 为 零 。

说 明

此 成 员 函 数 用 来 将 记 录 集 的 一 个 字 段 数 据 成 员 标 记 为 Null ( 专 指 没 有 值 ) 或 非空 。 当 应 用 程 序 将 一 个 新 记 录 增 加 到 一 个 记 录 集 中 时 , 其 所 有 字 段 数 据 成 员 初始 都 设 置 为 Null 值 , 并 标 记 为 “ 脏 的 ” ( 被 修 改 了 ) 。 当 应 用 程 序 从 一 个 数 据源 中 检 取 一 个 记 录 时 , 该 记 录 的 列 或 是 已 有 值 , 或 是 Null 。

注 意 此 成 员 函 数 对 使 用 成 组 行 检 取 的 记 录 集 是 不 适 用 的 。 如 果 你 已 经实 现 了 成 组 行 检 取 , 则 SetFieldDirty 将 导 致 一 个 失 败 断 言 。

如 果 你 特 别 希 望 将 当 前 记 录 的 某 个 字 段 设 计 为 没 有 值 ,可 将 bNull 设 置 为 TRUE 来 调 用 SetFieldNull 函 数 , 以 将 该 字 段 标 记 为 Null。 如 果 一 个 字 段 先 前 标 记 为Null , 而 现 在 应 用 程 序 想 要 给 它 一 个 值 , 则 只 需 要 简 单 地 设 置 该 字 段 的 新 值 。应 用 程 序 不 需 要 用 SetFieldNull 来 删 掉 Null 标 志 。 要 确 定 该 字 段 是 否 可 以 为

Null, 可 以 调 用 IsFieldNullable 函 数 。

重 点 只 能 在 调 用 Edit 或 AddNew 之 后 才 能 调 用 SetFieldNull 函 数 。

使 用 NULL 作 为 SetFieldNull 函 数 的 第 一 个 参 数 , 将 使 该 函 数 只 应 用 于

outputColumn s, 而 不 作 用 于 param s。 例 如 , 调 用

SetFieldNull( NULL );

将 只 设 置 outputColumns 为 NULL , 而 params 将 不 受 影 响 。

要 想 作 用 于 param s, 应 用 程 序 必 须 对 所 想 要 作 用 的 各 个 param 提 供 实 际 地 址 , 例 如 :

SetFieldNull( &m_strParam );

这 意 味 着 应 用 程 序 不 能 像 对 outputColumns 一 样 将 所 有 params 都 设 置 为 NULL 。

注 意 当 设 置 参 数 为 Null 时 , 在 记 录 集 打 开 之 前 调 用 SetFieldNull 将

导 致 一 个 断 言 。 在 这 种 情 况 下 , 可 以 调 用 SetParamNull 。

SetFieldNull 通 过 DoFieldExchange 实 现 。

请 参 阅 CRecordset::IsFieldNull, CRecordset::SetFieldDirty, CRecordset::Edit, CRecordset::Update, CRecordset::IsFieldNullable

CRecordset::SetLockingMode

void SetLockingMode( UINT nMode );

参 数

nMode

包 含 下 列 enum LockMode 枚 举 之 一 :

  • optimistic 乐 观 加 锁 方 式 , 仅 在 调 用 Update 期 间 加 锁 正 被 更 新 的 记录。

    • pessimistic 悲 观 加 锁 方 式 , 在 一 调 用 Edit 时 即 加 锁 ,

      并 保 持 加 锁 直 到

Update 调 用 完 成 , 或 移 动 到 一 个 新 记 录 。

说 明

如 果 应 用 程 序 需 要 指 定 记 录 集 用 于 更 新 的 两 种 记 录 加 锁 方 式 之 一 , 则 调 用 此 成员 函 数 。 缺 省 时 , 记 录 集 的 加 锁 方 式 是 optimistic 。 应 用 程 序 可 将 它 改 变 成 一 种更 为 谨 慎 的 pessimistic 加 锁 方 式 。 SetLockMode 调 用 应 该 在 应 用 程 序 构 造 并 打开 一 个 记 录 集 对 象 之 后 , 但 在 调 用 Edit 之 前 。

请 参 阅 CRecordset::Edit, CRecordset::Update

CRecordset::S etParamNull

void SetParamNull( int nIndex , NOOL bNull = TRUE );

参 数

nIndex

参 数 从 零 开 始 的 索 引 。

bNull

如 果 是 TRUE ( 缺 省 值 ) , 则 参 数 被 标 记 为 Null。 否 则 , 参 数 被 标 记 为 非

Null。

说 明

此 成 员 函 数 用 来 标 记 参 数 为 Null ( 专 指 没 有 值 ) 或 非 Null 。与 SetFieldNull 不一 样 , 你 可 以 在 打 开 记 录 集 之 前 调 用 SetParamNull 。

SetParamNull 通 常 是 用 来 进 行 预 定 义 查 询 的 。

请 参 阅 CRecordset::FlushResultSet

CRecordset::SetRowsetCursorPosition

void SetRowsetCursorPosition( WORD wRow , WORD wLockType = SQL_LOCK_NO_CHANGE );

参 数

wRow

当 前 记 录 集 中 一 行 的 从 1 开 始 的 位 置 。 这 个 值 的 范 围 可 以 是 从 1 到 此 行 集的 大 小 之 间 。

wLockType

一 个 值 , 指 定 在 行 被 刷 新 之 后 如 何 对 它 加 锁 。 有 关 的 细 节 , 参 见 说 明 部 分 。

说 明

此 成 员 函 数 用 来 将 游 标 移 动 到 当 前 行 集 中 的 一 行 。 当 实 现 成 组 行 检 取 时 , 通 过行 集 来 获 取 记 录 , 在 所 获 取 的 行 集 中 的 第 一 个 记 录 就 是 当 前 记 录 。 为 了 使 行 集

中 的 另 一 个 记 录 成 为 当 前 记 录 , 可 以 调 用 SetRowsetCursorPosition 。 例 如 , 你可 以 联 合 SetRowsetCursorPosition 和 GetFieldValue 成 员 函 数 来 动 态 地 获 取 你 的记 录 集 中 的 任 何 记 录 的 数 据 。

要 使 用 SetRowset Cursor Position , 你 必 须 在 O pen 成 员 函 数 的 dwOptions 参 数中 指 明 CRecordset::useMultiRowFetch 选 项 , 从 而 实 现 多 行 块 存 取 操 作 。

SetRowsetCursorPosition 调 用 ODBC API 函 数 SQLSetPo s 。 wLockType 参 数 指 定了 在 执 行 SQLSetPos 之 后 该 行 的 加 锁 状 态 。 下 面 的 表 格 描 述 了 wLockType 的 可能 取 值 。

W lockType 描述

SQL_LOCK_NO_CHANGE ( 缺

省 值 )

驱 动 器 和 数 据 源 保 证 该 行 的 加 锁 或 解 锁 状态 与 调 用 RefreshRowset 之 前 一 致

SQL_LOCK_EXCLUSIVE 驱 动 器 或 数 据 源 各 自 独 立 的 加 锁 该 行 。 不

是 所 有 的 数 据 源 都 支 持 这 种 加 锁 类 型

SQL_LOCK_UNLOCK 驱 动 器 或 数 据 源 解 锁 此 行 。 不 是 所 有 的 数

据 源 都 支 持 这 种 加 锁 类 型

有 关 SQLSetPos 的 更 多 信 息 , 请 参 见 “ ODBC SDK 程 序 员 参 考 ” 。

请 参 阅 CRecordset::RefreshRowset, CRecordset::SetRowsetSize

CRecordset::SetRowsetSize

virtual void SetRowsetSize( DWORD dwNewRowsetSize );

参 数

dwNewRowsetSize

在 一 次 给 定 的 检 取 中 要 获 取 的 行 数 。

说 明

在 使 用 成 组 行 检 取 时 , 此 虚 成 员 函 数 用 来 指 定 在 一 次 单 一 的 检 取 中 你 希 望 获 取的 行 数 。 要 实 现 成 组 行 检 取 , 你 必 须 在 Open 成 员 函 数 的 dwOptions 参 数 中 设置 CRecordset::use- MultiRowFetch 选 项 。

注 意 如 果 在 没 有 实 现 成 组 行 获 取 的 情 况 下 调 用 SetRowsetSize , 将 导 致一 个 失 败 断 言 。

在 调 用 Open 之 前 调 用 SetRowsetSize 来 初 始 设 置 记 录 集 的 行 集 的 大 小 。 在 实 现成 组 行 检 取 时 , 缺 省 的 行 集 大 小 是 25 。

注 意 在 调 用 SetRowsetSize 时 要 小 心 。 如 果 你 手 动 为 数 据 分 配 存 储 区

( 就 像 在 Open 中 的 dwOptions 参 数 的

CRecordset::userAllocMultiRowBuffers 选 项 所 指 定 的 一 样 ) , 你 应 该在 调 用 SetRowsetSize 之 后 , 但 在 执 行 任 何 游 标 导 航 操 作 之 前 , 检 查 是否 需 要 重 新 分 配 这 些 存 储 缓 冲 区 。

要 获 得 对 行 集 大 小 的 当 前 设 置 , 可 以 调 用 GetRowsetSize 。

请 参 阅 CRecordset::Open, CRecordset::GetRowsetSize, CRecordset::CheckRowsetError,

CRecordset::DoBulkFieldExchange

CRecordset::Update

virtual BOOL Update(); throw ( CDBException );

返 回 值

如 果 一 个 记 录 更 新 成 功 则 返 回 一 个 非 零 值 ; 否 则 如 果 没 有 列 改 变 , 则 返 回 值 为

零 。 如 果 没 有 记 录 被 更 新 , 或 有 多 个 记 录 被 更 新 , 则 抛 出 一 个 异 常 。 对 数 据 源上 的 其 它 任 何 失 败 也 都 将 抛 出 一 个 异 常 。

说 明

在 调 用 AddNew 或 Edit 成 员 函 数 之 后 , 调 用 Update 成 员 函 数 , 必 须 用 该 调 用来 完 成 AddNew 或 Edit 操 作 。

注 意 如 果 你 已 经 实 现 了 成 组 行 检 取 , 你 就 不 能 调 用 Update 。 这 将 导 致一 个 异 常 。 虽 然 类 CRecordset 不 提 供 更 新 成 组 行 数 据 的 机 制 , 但 是 你 可以 提 供 使 用 ODBC API 函 数 SQLSetPos 来 编 写 你 自 己 的 函 数 。 如 何 做 到 这一 点 , 请 参 见 例 子 DBFETCH 。

AddNew 或 Edit 都 准 备 了 一 个 编 辑 缓 冲 区 , 被 增 加 或 被 编 辑 的 数 据 都 放 在 此 缓冲 区 中 , 等 待 存 入 数 据 源 中 。 Update 保 存 这 些 数 据 。 只 有 标 记 为 或 检 测 为 被 修

改 了 的 那 些 字 段 才 被 更 新 。

如 果 数 据 源 支 持 事 务 , 你 可 以 使 Update 调 用 ( 以 及 它 的 相 应 的 AddNew 或 Edit

调 用 ) 成 为 事 务 的 一 部 分 。

警 告 如 果 你 没 有 先 调 用 AddNew 或 Edit 函 数 就 调 用 Update 函 数 , 则Update 函 数 将 抛 出 一 个 异 常 。 如 果 应 用 程 序 调 用 AddNew 或 Edit , 则 在调 用 MoveNext 之 前 , 或 改 变 记 录 集 或 数 据 源 之 前 , 必 须 调 用 Update 函数 。 否 则 , 所 做 的 改 变 将 丢 失 , 并 且 不 给 出 通 知 。

请 参 阅 CRecordset::Edit, CRecordset::AddNew, CRecordset::SetFieldDirty, CDBException

数 据 成 员

CRecordset::m_hstmt

说 明

此 数 据 成 员 包 含 与 此 记 录 集 相 关 联 的 ODBC 语 句 数 据 结 构 的 一 个 句 柄 , 类 型 为

HSTMT 。 对 一 个 ODBC 数 据 源 的 每 个 查 询 都 与 一 个 HSTMT 相 关 联 。

警 告 在 调 用 Open 前 不 要 使 用 m_hstmt 。

通 常 不 需 要 直 接 访 问 HSTMT , 但 是 在 直 接 执 行 S Q L 语 句 时 可 能 需 要 它 。 类

CDatabase 的 Exectu e SQL 成 员 函 数 提 供 了 使 用 m_h stm t 的 示 例 。

请 参 阅 C Database::ExecuteSQL

CRecordset::m_nFields

说 明

此 成 员 中 包 含 了 记 录 集 类 中 字 段 数 据 成 员 的 数 目 – – – 记 录 集 从 数 据 源 中 所 选 择的 列 数 。 记 录 集 必 须 用 当 前 数 目 初 始 化 m_nFields 成 员 。 当 应 用 程 序 使 用ClassWizard 来 声 明 应 用 程 序 的 记 录 集 类 时 , ClassWizard 将 为 应 用 程 序 编 写 这段 初 始 代 码 。 你 也 可 人 工 编 写 这 段 代 码 。

框 架 利 用 这 个 数 目 来 管 理 字 段 数 据 成 员 和 数 据 源 上 当 前 记 录 的 对 应 列 之 间 的 交互 。

重 点 在 利 用 参 数 CFieldExchange::outputColumn 调 用 SetFieldType 之 后 , 这 个 数 目 必 须 对 应 于 DoFieldExchange 中 注 册 的 “ 输 出 列 ” 的 数目 。

你 可 以 动 态 连 接 列 , 就 像 “ V isual C++ 程 序 员 指 南 ” 中 的 文 章 “ 记 录 集 : 动 态连 接 数 据 列 ” 所 描 述 的 一 样 。 如 果 这 样 做 , 你 就 必 须 增 加 m_nFields 中 的 计 数 , 以 反 映 DoFieldExchange 成 员 函 数 中 为 动 态 连 接 列 调 用 的 RFX 函 数 的 数 目 。

请 参 阅 CRecordset::DoFieldExchange, CRecordset::DoBulkFieldExchange, CRecordset::m_nParams, CFieldExchange::SetFieldType

CRecordset::m_nParams

说 明

此 成 员 中 包 含 记 录 集 类 中 参 数 数 据 成 员 的 数 目 – – – 传 递 给 记 录 集 的 程 序 的 参 数数 目 。 如 果 记 录 集 类 中 有 参 数 数 据 成 员 , 则 该 类 的 构 造 函 数 必 须 用 当 前 数 目 来初 始 化 m_nParams 成 员 。 m_nParams 的 缺 省 值 为 零 。 如 果 应 用 程 序 增 加 参 数 数据 成 员 – – – 这 必 须 手 动 进 行 – – – 则 也 必 须 在 类 构 造 函 数 中 手 动 地 增 加 一 个 初 始

化 , 以 反 映 参 数 数 目 ( 它 必 须 至 少 与 m_strFilter 或 m_strSort 字 符 串 中 的 占 位 符‘ ? ’ 数 目 一 样 多 ) 。

当 框 架 参 数 化 记 录 集 的 查 询 时 , 使 用 这 个 成 员 中 的 数 目 。

重 点 在 用 CFieldExchange::inputParam , CFieldExchange::param , CFieldExchange:: outputParam , 或 CFieldExchange::inoutParam 为 参数 调 用 SetFieldType 之 后 ,这 个 成 员 的 数 目 必 须 对 应 于 DoFieldExchange 或 DoBulkFieldExchange 中 注 册 的 “ params ” 的 数 目 。

请 参 阅 CRecordset::DoFieldExchange, CRecordset::DoBulkFieldExchange, CRecordset::m_nFields, CFieldExchange::SetFieldType

CRecordset::m_pDatabase

说 明

此 成 员 包 含 了 一 个 指 向 CDatabase 对 象 的 指 针 , 记 录 集 通 过 此 对 象 连 接 到 一 个数 据 源 上 。 这 个 成 员 变 量 可 用 两 种 方 式 设 置 。 通 常 来 说 , 在 应 用 程 序 构 造 记 录集 对 象 时 , 传 递 一 个 指 向 已 经 连 接 的 CDatabase 对 象 的 指 针 。 如 果 应 用 程 序 传递 的 是 NULL , 则 CRecordset 为 应 用 程 序 重 建 一 个 CDatabase 对 象 并 连 接 该 对象 。 在 这 两 种 情 况 下 , CRecordset 都 将 指 针 存 放 在 此 成 员 变 量 中 。

一 般 来 说 , 你 不 需 要 直 接 使 用 m_pDatabase 中 所 存 储 的 指 针 。 不 过 , 如 果 你 想要 编 制 自 己 对 CRecordset 的 扩 展 , 则 可 能 会 使 用 这 个 指 针 。 例 如 , 如 果 你 抛 出自 己 的 CDBException 异 常 , 则 你 也 许 会 需 要 这 个 指 针 。 或 者 , 如 果 你 需 要 用相 同 的 CRecordset 对 象 来 做 一 些 事 情 , 例 如 运 行 事 务 , 设 置 超 时 中 断 , 或 调 用

CDatabase 类 的 ExecuteSQL 成 员 函 数 来 直 接 执 行 S Q L 语 句 , 则 也 可 能 需 要 用到 这 个 数 据 成 员 中 的 指 针 。

CRecordset::m_strFilter

说 明

在 应 用 程 序 构 造 了 记 录 集 对 象 之 后 , 但 在 调 用 该 对 象 的 Open 成 员 函 数 之 前 , 使 用 此 数 据 成 员 来 存 放 一 个 CString, 其 中 包 含 一 条 SQL WHERE 子 句 。 记 录集 利 用 这 个 字 符 串 来 限 制 – –– 或 过 滤 – –– 它 在 Open 或 Requery 调 用 期 间 可 选 择的 记 录 。 这 可 用 于 选 择 记 录 的 一 个 子 集 , 例 如 “ all salespersons based in California ” ( “ state = CA ” ) 。 一 条 WHERE 子 句 的 ODBC SQL 语 法 是

WHERE serch-condition (查询条件)。

注 意 , 在 该 字 符 串 中 不 要 包 括 WHERE 关 键 字 。 框 架 会 提 供 这 个 关 键 字 的 。

应 用 程 序 也 可 以 通 过 在 过 滤 串 中 放 ‘ ? ’ 占 位 字 符 , 在 记 录 集 类 中 为 每 个 占 位字 符 声 明 一 个 参 数 数 据 成 员 , 并 在 运 行 时 传 递 参 数 给 记 录 集 , 来 参 数 化 过 滤 串 。这 使 应 用 程 序 可 以 在 运 行 时 构 造 过 滤 串 。

示 例

// CRecordset::m_strFilter 示 例

CCustSet rsCustSet( NULL );

// 设 置 过 滤 串

rsCustSet.m_strFilter = "state = 'CA'";

// 运 行 过 滤 后 的 查 询

rsCustSet.Open( CRecordset::snapshot, "Customers" );

请 参 阅 CRecordset::m_strSort, CRecordset::Requery

CRecordset::m_strSort

说 明

在 应 用 程 序 构 造 了 记 录 集 对 象 之 后 , 但 在 调 用 此 类 的 Open 成 员 函 数 之 前 , 使用 此 数 据 成 员 来 存 储 一 个 CString, 其 中 包 含 一 条 SQL ORDERBY 子 句 。 记 录集 利 用 这 个 字 符 串 来 排 序 它 在 Open 或 Requery 调 用 期 间 选 择 的 记 录 。 应 用 程序 可 以 利 用 这 个 特 性 , 对 记 录 集 按 一 列 或 多 列 进 行 排 序 。 一 条 ORDER BY 子

句 的 ODBC 语 法 是

ORDER BY sort-specification[,sort-specification]...

在 此 一 个 sort-specification ( 排 序 规 范 ) 是 一 个 整 数 或 一 个 列 名 。 应 用 程 序 也 可以 通 过 在 排 序 字 符 串 中 的 列 表 后 添 加 上 “ ASC ” 或 “ DESC ” 来 指 定 是 升 序 还是 降 序 ( 缺 省 是 升 序 ) 。 所 选 记 录 首 先 按 第 一 列 排 序 , 然 后 按 第 二 列 排 序 , 如

此 等 等 。 例 如 , 可 以 先 按 人 名 的 尾 名 对 “ Customers ” 记 录 集 进 行 排 序 , 再 按 人名 的 首 名 对 该 记 录 集 进 行 排 序 。更 多 的 信 息 ,可 参 见“ ODBC SDK 程 序 员 参 考 ”。

注 意 , 在 排 序 字 符 串 中 不 要 包 括 ORDER BY 关 键 字 , 框 架 会 提 供 这 个 关 键 字 。

示 例

// CRecordset::m_strSort 示 例

CCustSet rsCustSet( NULL );

// 设 置 排 序 字 符 串

rsCustSet.m_strSort = "District, Last_Name";

// 运 行 整 理 后 的 查 询

rsCustSet.Open( CRecordset::snapshot, "Customers" );

请 参 阅 CRecordset::m_strFilter, CRecordset::Requery