Share via


记录字段交换:RFX 的工作方式

本主题介绍 RFX 过程。 这是一个高级主题,涵盖以下方面:

注意

本主题适用于从 CRecordset 派生的类,其中尚未实现批量提取行。 如果使用批量提取行,则将实现批量记录字段交换(批量 RFX)。 批量 RFX 与 RFX 类似。 若要了解区别,请参阅记录集:批量提取记录 (ODBC)

RFX 和记录集

记录集对象的字段数据成员一起构成了一个编辑缓冲区,此缓冲区保存一条记录的选定列。 当记录集第一次打开并即将读取第一条记录时,RFX 将每个选定的列绑定(关联)到相应字段数据成员的地址。 当记录集更新记录时,RFX 调用 ODBC API 函数将 SQL UPDATE 或 INSERT 语句发送到驱动程序。 RFX 根据自身对字段数据成员的认知来指定要写入的列。

框架在某些阶段备份编辑缓冲区,以便在必要时还原其内容。 RFX 在添加新记录之前和编辑现有记录之前备份编辑缓冲区。 在某些情况下,它会恢复编辑缓冲区,例如,在 AddNew 之后进行 Update 调用。 如果你放弃新更改的编辑缓冲区,例如在调用 Update 之前移动到另一条记录,则不会还原编辑缓冲区。

除了在数据源和记录集的字段数据成员之间交换数据外,RFX 还管理绑定参数。 打开记录集时,任何参数数据成员都按照 CRecordset::Open 构造的 SQL 语句中的“?”占位符的顺序绑定。 有关详细信息,请参阅记录集:参数化记录集 (ODBC)

记录集类对 DoFieldExchange 的重写将完成所有工作,在两个方向上移动数据。 与对话数据交换 (DDX) 一样,RFX 需要有关你的类的数据成员的信息。 该向导根据你使用向导指定的字段数据成员名称和数据类型,通过为你编写特定于记录集的 DoFieldExchange 实现来提供必要的信息。

记录字段交换过程

本节描述打开记录集对象以及添加、更新和删除记录时的 RFX 事件序列。 本主题中的记录集打开期间 RFX 操作序列表和滚动期间的 RFX 操作序列表显示了 RFX 处理记录集中的 Move 命令和 RFX 管理更新的过程。 在这些过程中,会调用 DoFieldExchange 来执行许多不同的操作。 CFieldExchange 对象的 m_nOperation 数据成员确定请求哪个操作。 在阅读本材料之前,阅读记录集:记录集如何选择记录 (ODBC)记录集:记录集如何更新记录 (ODBC) 将很有帮助。

RFX:列和参数的初始绑定

调用记录集对象的 Open 成员函数时,会按所示顺序发生以下 RFX 活动:

  • 如果记录集具有参数数据成员,则框架调用 DoFieldExchange 以将参数绑定到记录集的 SQL 语句字符串中的参数占位符。 在 SELECT 语句中找到的每个占位符都使用与数据类型相关的参数值表示。 执行此操作的时间是在 SQL 语句准备好之后且在执行之前。 有关语句准备的信息,请参阅 ODBC 程序员参考中的 ::SQLPrepare 函数。

  • 框架再次调用 DoFieldExchange 以将选定列的值绑定到记录集中相应的字段数据成员。 这将记录集对象建立为包含第一条记录的列的编辑缓冲区。

  • 记录集执行 SQL 语句,且数据源选择第一条记录。 记录的列被加载到记录集的字段数据成员中。

以下表格显示了打开记录集时的 RFX 操作顺序。

记录集打开期间的 RFX 操作顺序

你的操作 DoFieldExchange 操作 数据库/SQL 操作
1. 打开记录集。
2. 构建 SQL 语句。
3. 发送 SQL。
4. 绑定参数数据成员。
5. 将字段数据成员绑定到列。
6. ODBC 执行移动并填写数据。
7. 修复 C++ 的数据。

记录集使用 ODBC 的准备执行来允许使用相同的 SQL 语句进行快速重新查询。 有关准备执行的详细信息,请参阅 ODBC 程序员参考

RFX:滚动

当你从一条记录滚动到另一条记录时,框架调用 DoFieldExchange 以将先前存储在字段数据成员中的值替换为新记录的值。

以下表格显示了用户从一个记录移动到另一个记录时的 RFX 操作顺序。

滚动期间的 RFX 操作顺序

你的操作 DoFieldExchange 操作 数据库/SQL 操作
1. 调用 MoveNext 或某个其他移动函数。
2. ODBC 执行移动并填写数据。
3. 修复 C++ 的数据。

RFX:添加新记录和编辑现有记录

如果你添加新记录,则记录集将作为编辑缓冲区来构建新记录的内容。 与添加记录一样,编辑记录涉及更改记录集的字段数据成员的值。 从 RFX 的角度来看,顺序如下:

  1. 你对记录集的 AddNewEdit 成员函数的调用会导致 RFX 存储当前的编辑缓冲区,以便以后可以恢复它。

  2. AddNewEdit 准备编辑缓冲区中的字段,以便 RFX 可以检测更改的字段数据成员。

    因为新记录没有以前的值来比较新记录,所以 AddNew 会将每个字段数据成员的值设置为 PSEUDO_NULL 值。 稍后,当你调用 Update 时,RFX 会将每个数据成员的值与 PSEUDO_NULL 值进行比较。 如果有差异,则数据成员已设置。 (PSEUDO_NULL 与具有真正 Null 值的记录列不同,也不与 C++ NULL 相同。)

    不同于对 AddNew 调用 Update,对 Edit 调用 Update 将更新的值与以前存储的值进行比较,而不是使用 PSEUDO_NULL。 不同之处在于,AddNew 没有先前存储的值进行比较。

  3. 你直接设置要编辑其值或要为新记录填充的字段数据成员的值。 这可以包括调用 SetFieldNull

  4. 调用 Update 会检查已更改的字段数据成员,如步骤 2 中所述(请参阅表 RFX 滚动期间的操作顺序)。 如果没有任何变化,则 Update 返回 0。 如果某些字段数据成员已更改,则 Update 准备并执行一条 SQL INSERT 语句,该语句包含记录中所有已更新字段的值。

  5. 对于 AddNewUpdate 将通过恢复 AddNew 调用前由当前记录的先前存储的值来结束。 对于 Edit,新的值和已编辑的值保持不变。

下表显示了添加新记录或编辑现有记录时的 RFX 操作顺序。

AddNew 和 Edit 期间的 RFX 操作顺序

你的操作 DoFieldExchange 操作 数据库/SQL 操作
1. 调用 AddNewEdit
2. 备份编辑缓冲区。
3. 对于 AddNew,将字段数据成员标记为“clean”和 Null。
4. 为记录集字段数据成员赋值。
5. 调用 Update
6. 检查是否有更改的字段。
7. 为 AddNew 构建 SQL INSERT 语句,或为 Edit 构建 UPDATE 语句。
8. 发送 SQL。
9. 对于 AddNew,将编辑缓冲区还原为其备份的内容。 对于 Edit,删除备份。

RFX:删除现有记录

当你删除一条记录时,RFX 会将所有字段设置为 NULL,以提醒你此记录已被删除,你必须将此记录移出。 你不需要任何其他 RFX 序列信息。

另请参阅

记录字段交换 (RFX)
MFC ODBC 使用
宏、全局函数和全局变量
CFieldExchange 类
CRecordset::DoFieldExchange