记录集:有关更新的更多信息 (ODBC)

本主题适用于 MFC ODBC 类。

本主题介绍:

注意

本主题适用于从 CRecordset 派生的对象,其中尚未实现批量提取行。 如果已实现批量行提取,则某些信息则不适用。 例如,无法调用 AddNewEditDeleteUpdate 成员函数;但可以执行事务。 有关批量行提取的详细信息,请参阅记录集:批量提取记录 (ODBC)

其他操作如何影响更新

更新时生效的事务、在完成事务之前关闭记录集以及在完成事务之前进行滚动都会影响更新。

事务如何影响更新

除了了解 AddNewEditDelete 的工作原理之外,了解 CDatabaseBeginTransCommitTransRollback 成员函数如何与 CRecordset 的更新函数配合工作也很重要。

默认情况下,当你调用 Update 时,对 AddNewEdit 的调用会立即影响数据源。 Delete 调用会立即生效。 但你可以建立一个事务并执行一批此类调用。 在提交更新之前,更新不是永久性的。 如果你改变了主意,可以回滚事务而不要提交它。

有关事务的详细信息,请参阅事务 (ODBC)

关闭记录集如何影响更新

如果你关闭某个记录集或其关联的 CDatabase 对象,而某个事务正在进行(尚未调用 CDatabase::CommitTransCDatabase::Rollback),则该事务会自动回滚(除非数据库后端是 Microsoft Jet 数据库引擎)。

注意

如果使用的是 Microsoft Jet 数据库引擎,则关闭显式事务内部的记录集不会导致释放任何已修改的行,或者在显式提交或回滚事务之前放置的锁。 建议始终在显式 Jet 事务内部或外部打开和关闭记录集。

滚动如何影响更新

在记录集中执行记录集:滚动 (ODBC) 操作时,编辑缓冲区中会填充每个新的当前记录(不首先存储先前的记录)。 滚动会跳过先前已删除的记录。 如果在执行 AddNewEdit 调用之后滚动且不先调用 UpdateCommitTransRollback,则任何更改都会丢失(不会发出警告),因为新记录将引入到编辑缓冲区中。 编辑缓冲区中会填充滚动到的记录,存储的记录将被释放,数据源不会发生任何更改。 这适用于 AddNewEdit

你的更新和其他用户的更新

当你使用记录集更新数据时,你的更新会影响其他用户。 同样,在记录集的生存期内由其他用户做出的更新也会影响你。

在多用户环境中,其他用户可能会打开包含你在自己的记录集中选择的某些相同记录的记录集。 你在检索记录之前对其所做的更改会反映在你的记录集中。 由于每次滚动到某个记录时,动态集都会检索该记录,因此每次滚动到记录时,动态集都会反映更改。 快照会在你首次滚动到某个记录时检索该记录,因此快照仅反映你在最初滚动到记录之前发生的更改。

除非重新查询,否则在你打开记录集后由其他用户添加的记录不会显示在你的记录集中。 如果你的记录集是动态集,当你滚动到受影响的记录时,其他用户对现有记录进行的编辑确实会显示在你的动态集中。 如果你的记录集是快照,则在重新查询快照之前不会显示编辑内容。 如果你想要查看其他用户在你的快照中添加或删除的记录,或者其他用户在你的动态集中添加的记录,请调用 CRecordset::Requery 来重新生成记录集。 (请注意,其他用户的删除内容会显示在你的动态集中。)也可以调用 Requery 来查看你添加的记录,但无法查看你的删除内容。

提示

若要强制一次性缓存整个快照,请在打开快照后立即调用 MoveLast。 然后调用 MoveFirst 开始处理记录。 MoveLast 等效于滚动所有记录,但会一次性检索所有记录。 但请注意,这可能会降低性能,对于某些驱动程序而言可能不需要这样做。

更新对其他用户的影响类似于对你的影响。

有关 Update 和 Delete 的详细信息

本部分提供更多信息来帮助你使用 UpdateDelete

更新成功和失败

如果 Update 成功,则 AddNewEdit 模式结束。 若要再次开始 AddNewEdit 模式,请调用 AddNewEdit

如果 Update 失败(返回 FALSE 或引发异常),则你会保持 AddNewEdit 模式,具体取决于最后调用的函数。 你可以随后执行以下操作之一:

  • 修改字段数据成员并重试 Update

  • 调用 AddNew 将字段数据成员重置为 Null,设置字段数据成员的值,然后再次调用 Update

  • 调用 Edit 以重新加载首次调用 AddNewEdit 之前记录集中的值,设置字段数据成员的值,然后再次调用 Update。 在成功调用 Update 之后(但不包括调用 AddNew 之后),字段数据成员将保留其新值。

  • 调用 Move(包括使用 AFX_MOVE_REFRESH 参数或 0 调用 Move),这会刷新所有更改并结束任何生效的 AddNewEdit 模式。

Update 和 Delete

本部分适用于 UpdateDelete

执行 UpdateDelete 操作时,应该更新一条(且只能是一条)记录。 该记录是当前记录,它对应于记录集字段中的数据值。 如果出于某种原因而没有任何记录受到影响或者有多个记录受到影响,则会引发包含以下 RETCODE 值之一的异常

  • AFX_SQL_ERROR_NO_ROWS_AFFECTED

  • AFX_SQL_ERROR_MULTIPLE_ROWS_AFFECTED

引发这些异常时,你会保持调用 UpdateDelete 时所处的 AddNewEdit 状态。 下面是会发生这些异常的最常见场景。 很有可能出现的情况:

  • 当你使用乐观锁定模式,而另一个用户以阻止框架识别要更新或删除的正确记录的方式修改记录时,出现 AFX_SQL_ERROR_NO_ROWS_AFFECTED。

  • 当你正在更新的表没有主键或唯一索引,并且记录集中没有足够的列用于唯一标识表行时,出现 AFX_SQL_ERROR_MULTIPLE_ROWS_AFFECTED。

另请参阅

记录集 (ODBC)
记录集:记录集如何选择记录 (ODBC)
记录字段交换 (RFX)
SQL
异常:数据库异常