本主题适用于从
CRecordset
派生的对象,其中尚未实现批量提取行。 如果使用批量提取行,请参阅
记录集:批量提取记录 (ODBC)
。
作为补充,你可能需要阅读
记录字段交换:RFX 的工作原理
,其中描述了 RFX 在更新操作中的相应角色。
向记录集添加新记录涉及调用记录集的
AddNew
成员函数、设置新记录的字段数据成员的值,以及调用
Update
成员函数以将记录写入数据源。
作为调用
AddNew
的前提条件,记录集不得以只读方式打开。 使用
CanUpdate
和
CanAppend
成员函数可以确定这些条件。
调用
AddNew
时:
将存储编辑缓冲区中的记录,因此如果取消该操作,可以还原其内容。
将标记字段数据成员,因此以后可以检测其中的更改。 字段数据成员也标记为干净(未更改)并设置为 Null。
调用
AddNew
后,编辑缓冲区表示新的空记录,可以在其中填充值。 为此,可以通过分配值来手动设置这些值。 可以调用
SetFieldNull
来指定值 Null,而不是为字段指定实际数据值。
若要提交更改,请调用
Update
。 为新记录调用
Update
时:
如果 ODBC 驱动程序支持
::SQLSetPos
ODBC API 函数,则 MFC 将使用该函数在数据源上添加记录。 使用
::SQLSetPos
,MFC 可以更高效地添加记录,因为它不必构造和处理 SQL 语句。
如果无法使用
::SQLSetPos
,MFC 将执行以下操作:
如果未检测到任何更改,
Update
不执行任何操作并返回 0。
如果有更改,
Update
将构造 SQL INSERT 语句
。 所有脏字段数据成员表示的列都列在 INSERT 语句中
。 若要强制包含列,请调用
SetFieldDirty
成员函数:
SetFieldDirty( &m_dataMember, TRUE );
Update
提交新记录 - 执行 INSERT 语句,并将记录提交到数据源(以及记录集,如果不是快照)上的表,除非事务正在进行中。
存储的记录将还原到编辑缓冲区。 无论 INSERT 语句是否已成功执行,调用 AddNew
之前的当前记录都会再次成为当前记录。
若要完全控制新记录,请采用以下方法:设置将具有值的任何字段的值,然后通过使用指向字段的指针和参数 TRUE(默认值)调用 SetFieldNull
来显式设置将保持 Null 的任何字段。 如果要确保不将某个字段写入数据源,请使用指向该字段的指针和参数 FALSE 调用 SetFieldDirty
,并且不要修改字段的值。 若要确定是否允许某个字段为 Null,请调用 IsFieldNullable
。
为了检测记录集数据成员何时更改值,MFC 使用适用于可以存储在记录集中的每种数据类型的 PSEUDO_NULL 值。 如果必须将字段显式设置为 PSEUDO_NULL 值,并且该字段恰好已标记为 Null,则还必须调用 SetFieldNull
,在第一个参数中传递字段的地址,在第二个参数中传递 FALSE。
添加的记录的可见性
添加的记录何时对记录集可见? 添加的记录有时会显示,有时不可见,具体取决于两项因素:
驱动程序能够执行的操作。
框架可以利用的内容。
如果 ODBC 驱动程序支持 ::SQLSetPos
ODBC API 函数,则 MFC 将使用该函数添加记录。 使用 ::SQLSetPos
,添加的记录对任何可更新的 MFC 记录集都可见。 如果没有对函数的支持,则添加的记录不可见,必须调用 Requery
才能查看这些记录。 使用 ::SQLSetPos
也更高效。
编辑现有记录
编辑记录集中的现有记录涉及滚动到记录、调用记录集的 Edit 成员函数、设置新记录的字段数据成员的值以及调用 Update 成员函数以将更改的记录写入数据源。
作为调用 Edit
的前提条件,记录集必须是可更新的并且位于记录上。 使用 CanUpdate
和 IsDeleted
成员函数可以确定这些条件。 当前记录也必须尚未删除,并且记录集中必须有记录(IsBOF
和 IsEOF
返回 0)。
调用 Edit
时,将存储编辑缓冲区(当前记录)中的记录。 稍后将使用存储的记录的值来检测是否有任何字段已更改。
调用 Edit
后,编辑缓冲区仍表示当前记录,但现在已准备好接受对字段数据成员的更改。 若要更改记录,请手动设置要编辑的任何字段数据成员的值。 可以调用 SetFieldNull
来指定值 Null,而不是为字段指定实际数据值。 若要提交更改,请调用 Update
。
若要退出 AddNew
或 Edit
模式,请使用参数 AFX_MOVE_REFRESH 调用 Move
。
作为调用 Update
的前提条件,记录集不得为空,并且不得已删除当前记录。 IsBOF
、IsEOF
和 IsDeleted
都应返回 0。
为已编辑的记录调用 Update
时:
如果 ODBC 驱动程序支持 ::SQLSetPos
ODBC API 函数,则 MFC 将使用该函数在数据源上更新记录。 使用 ::SQLSetPos
,驱动程序会将编辑缓冲区与服务器上的相应记录进行比较,如果两者不同,则更新服务器上的记录。 使用 ::SQLSetPos
,MFC 可以更高效地更新记录,因为它不必构造和处理 SQL 语句。
- 或 -
如果无法使用 ::SQLSetPos
,MFC 将执行以下操作:
如果没有更改,Update
不执行任何操作并返回 0。
如果有更改,Update
将构造 SQL UPDATE 语句。 UPDATE 语句中列出的列基于已更改的字段数据成员。
Update
提交更改(执行 UPDATE 语句),数据源上的记录发生更改,但如果事务正在进行,则不会提交(有关事务如何影响更新的信息,请参阅事务:在记录集中执行事务 (ODBC))。 ODBC 保留记录的副本,该副本也会更改。
与 AddNew
过程不同,Edit
过程不会还原存储的记录。 已编辑的记录将保留为当前记录。
准备通过调用 Update
来更新记录集时,请注意记录集包括构成表主键的所有列(或表上任何唯一索引的所有列,或可唯一标识行的足够多的列)。 在某些情况下,框架只能使用在记录集中选择的列来标识表中要更新的记录。 如果没有所有必要的列,则可能会更新表中的多个记录。 在这种情况下,调用 Update
时,框架会引发异常。
如果在之前调用任一函数后但在调用 Update
之前调用 AddNew
或 Edit
,则编辑缓冲区将使用存储的记录刷新,从而替换正在添加或编辑的记录。 此行为提供了一种中止 AddNew
或 Edit
并开始处理新记录的方法:如果确定正在处理的记录有问题,只需再次调用 Edit
或 AddNew
。
从记录集中删除记录涉及滚动到该记录并调用记录集的 Delete 成员函数。 与 AddNew
和 Edit
不同,Delete
不需要对 Update
进行匹配调用。
作为调用 Delete
的前提条件,记录集必须是可更新的,并且必须位于记录上。 使用 CanUpdate
、IsBOF
、IsEOF
和 IsDeleted
成员函数可以确定这些条件。
调用 Delete
时:
如果 ODBC 驱动程序支持 ::SQLSetPos
ODBC API 函数,则 MFC 将使用该函数在数据源上删除记录。 使用 ::SQLSetPos
通常比使用 SQL 更高效。
- 或 -
如果无法使用 ::SQLSetPos
,MFC 将执行以下操作:
编辑缓冲区中的当前记录不会像 AddNew
和 Edit
中那样备份。
Delete
构造一个删除记录的 SQL DELETE 语句。
编辑缓冲区中的当前记录不会像 AddNew
和 Edit
中那样存储。
Delete
提交删除 - 执行 DELETE 语句。 记录在数据源上标记为已删除,如果记录是快照,则在 ODBC 中标记为已删除。
已删除记录的值仍位于记录集的字段数据成员中,但字段数据成员标记为 Null,并且记录集的 IsDeleted
成员函数返回非零值。
删除记录后,应滚动到另一条记录以使用新记录的数据重新填充编辑缓冲区。 再次调用 Delete
或调用 Edit
会出错。
有关更新操作中使用的 SQL 语句的信息,请参阅 SQL。
记录集 (ODBC)
记录集:有关更新的更多信息 (ODBC)
记录字段交换 (RFX)
即将推出:在整个 2024 年,我们将逐步取消以“GitHub 问题”作为内容的反馈机制,并将其替换为新的反馈系统。 有关详细信息,请参阅:https://aka.ms/ContentUserFeedback。
提交和查看相关反馈