BOOL IsOpen() const;
如果记录集对象的 Open 或 Requery 成员函数以前已调用且记录集尚未关闭,则为非零值;否则为 0。
CRecordset::m_hstmt
包含与记录集关联的类型为 HSTMT 的 ODBC 语句数据结构的句柄。
对 ODBC 数据源的每个查询都与 HSTMT 关联。
在调用 m_hstmt 之前不要使用 Open。
通常不需要直接访问 HSTMT,但可能需要它来直接执行 SQL 语句。
ExecuteSQL 类的 CDatabase 成员函数提供了 m_hstmt 使用示例。
CRecordset::m_nFields
包含记录集类中的字段数据成员数;也就是说,记录集从数据源中选择的列数。
记录集类的构造函数必须用正确的数字初始化 m_nFields。 如果尚未实现批量行提取,ClassWizard 将在你使用它来声明记录集类时为你编写此初始化。 你也可以手动编写此初始化。
框架使用此数字来管理字段数据成员与数据源上当前记录的相应列之间的交互。
该数字必须与使用 DoFieldExchange 参数调用 DoBulkFieldExchange 后在 SetFieldType 或 CFieldExchange::outputColumn 中注册的“输出列”数相对应。
可以动态绑定列,如“记录集:动态绑定数据列”一文中所述。如果这样做,则必须增加 m_nFields 计数,以反映动态绑定列的 DoFieldExchange 或 DoBulkFieldExchange 成员函数中 RFX 或批量 RFX 函数调用数。
有关详细信息,请参阅文章记录集:动态绑定数据列 (ODBC) 和记录集:批量提取记录 (ODBC)。
请参阅记录字段交换:使用 RFX。
CRecordset::m_nParams
包含记录集类中参数数据成员的数量;也就是说,与记录集查询一起传递的参数数量。
如果记录集类具有任何参数数据成员,则类的构造函数必须用正确数字初始化 m_nParams。
m_nParams 默认值为 0。 如果添加参数数据成员(必须手动),还必须在类构造函数中手动添加初始化,以反映参数数量(必须至少与 m_strFilter 或 m_strSort 字符串中的 '' 占位符的数量相同。)
框架在参数化记录集的查询时使用此数字。
该数字必须与使用 DoFieldExchange、DoBulkFieldExchange、SetFieldType 或 CFieldExchange::inputParam 参数调用 CFieldExchange::param 后在 CFieldExchange::outputParam 或 CFieldExchange::inoutParam 中注册的“参数”数量相对应。
请参阅文章记录集:参数化记录集 (ODBC) 和记录字段交换:使用 RFX。
CRecordset::m_pDatabase
包含指向 CDatabase 对象的指针,记录集通过该对象连接到数据源。
此变量有两种设置方式。 通常,构造记录集对象时,会将指针传递给已连接的 CDatabase 对象。 如果改为传递 NULL,CRecordset 将为你创建 CDatabase 对象并连接它。 在这两种情况下,CRecordset 将指针存储在此变量中。
通常,你不需要直接使用存储在 m_pDatabase 中的指针。 但是,如果编写自己的 CRecordset 扩展,则可能需要使用指针。 例如,如果引出自己的 CDBException,则可能需要指针。 或者,如果需要使用同一 CDatabase 对象执行某些操作,例如运行事务、设置超时或调用 ExecuteSQL 类 CDatabase 成员函数来直接执行 SQL 语句,则可能需要它。
CRecordset::m_strFilter
构造记录集对象之后,但在调用其 Open 成员函数之前,使用此数据成员来存储包含 SQL CString 子句的 WHERE。
记录集使用此字符串来约束(或筛选)在调用 Open 或 Requery 期间选择的记录。 这对于选择记录的子集非常有用,例如“所有在加州的销售人员”(“state = CA”)。
WHERE 子句的 ODBC SQL 语法为
WHERE search-condition
不要在字符串中包含 WHERE 关键字。 框架会提供它。
还可以通过在筛选器字符串中放置 '' 占位符、为每个占位符在类中声明参数数据成员以及在运行时将参数传递给记录集来参数化筛选器字符串。 这样就可以在运行时构造筛选器。 有关详细信息,请参阅记录集:参数化记录集 (ODBC)。
有关 SQL WHERE 子句的详细信息,请参阅 SQL。 有关选择和筛选记录的详细信息,请参阅记录集:筛选记录 (ODBC)。
CCustomer rsCustSet(&m_dbCust);
// Set the filter
rsCustSet.m_strFilter = _T("L_Name = 'Flanders'");
// Run the filtered query
rsCustSet.Open(CRecordset::snapshot, _T("Customer"));
CRecordset::m_strSort
构造记录集对象之后,但在调用其 Open 成员函数之前,使用此数据成员来存储包含 SQL CString 子句的 ORDER BY。
记录集使用此字符串对在调用 Open 或 Requery 期间选择的记录进行排序。 可以使用此功能对一个或多个列的记录集进行排序。
ORDER BY 子句的 ODBC SQL 语法为
ORDER BY sort-specification [, sort-specification]...
其中,排序规范是整数或列名。 还可以通过在排序字符串的列列表中添加“ASC”或“DESC”来指定升序或降序(默认为升序)。 所选记录首先按列出的第一列进行排序,然后按第二列排序,依此类推。 例如,可以按姓和名对“Customers”记录集进行排序。 可以列出的列数取决于数据源。 有关详细信息,请参阅 Windows SDK。
不要在字符串中包含 ORDER BY 关键字。 框架会提供它。
有关 SQL 子句的详细信息,请参阅 SQL。 有关对记录进行排序的详细信息,请参阅记录集:对记录进行排序 (ODBC)。
CCustomer rsCustSet(&m_dbCust);
// Set the sort string
rsCustSet.m_strSort = _T("L_Name, ContactFirstName");
// Run the sorted query
rsCustSet.Open(CRecordset::snapshot, _T("Customer"));
CRecordset::Move
在记录集中向前或向后移动当前记录指针。
virtual void Move(
long nRows,
WORD wFetchType = SQL_FETCH_RELATIVE);
nRows
向前或向后移动的行数。 正值朝记录集末尾向前移动。 负值朝开头向后移动。
wFetchType
确定 Move 将提取的行集。 有关详细信息,请参阅“备注”。
如果为 nRows 传递值 0,则 Move 将刷新当前记录;Move 将结束任何当前 AddNew 或 Edit 模式,并在调用 AddNew 或 Edit 之前还原当前记录的值。
在记录集中移动时,无法跳过已删除的记录。 有关详细信息,请参阅CRecordset::IsDeleted。 当你打开设置了 CRecordset 选项的 skipDeletedRecords 时,如果 Move 参数为 0,则 nRows 将断言。 此行为可防止刷新使用相同数据的其他客户端应用程序删除的行。 有关 dwOption 的描述,请参阅 Open 中的 skipDeletedRecords 参数。
Move 按行集重新定位记录集。 根据 nRows 和 wFetchType 的值,Move 提取相应的行集,然后将该行集中的第一条记录制作为当前记录。 如果尚未实现批量行提取,则行集大小始终为 1。 提取行集时,Move 直接调用 CheckRowsetError 成员函数来处理提取产生的任何错误。
根据传递的值,Move 等效于其他 CRecordset 成员函数。 具体而言,wFetchType 的值可能指示一个更直观的成员函数,通常是移动当前记录的首选方法。
下表列出了 wFetchType 可能的值、Move 将基于 wFetchType 和 nRows 提取的行集,以及对应于 wFetchType 的任何等效成员函数。
wFetchType
提取的行集
等效成员函数
SQL_FETCH_ABSOLUTE
如果 nRows> 0,则从记录集开头开始 nRows 行的行集。 如果 nRows< 0,则从记录集末尾开始 nRows 行的行集。 如果 nRows = 0,则返回文件开头 (BOF) 条件。
SetAbsolutePosition
SQL_FETCH_BOOKMARK
从书签值对应于 nRows 的行开始的行集。
SetBookmark
如果已滚动到记录集的开头或结尾(IsBOF 或 IsEOF 返回非零值),则调 Move 用函数可能会引发 CDBException。 例如,如果 IsEOF 返回非零值而 IsBOF 没有返回非零值,则 MoveNext 将引发异常,但 MovePrev 不会引发异常。
如果在更新或添加当前记录时调用 Move,更新将丢失,而不会发出警告。
有关记录集导航的详细信息,请参阅文章“记录集:滚动 (ODBC)”和“记录集:书签和绝对位置 (ODBC)”。 有关批量行提取的详细信息,请参阅记录集:批量提取记录 (ODBC)。 相关信息请参阅 Windows SDK 中的 ODBC API 函数SQLExtendedFetch。
// rs is a CRecordset or a CRecordset-derived object
// Change the rowset size to 5
rs.SetRowsetSize(5);
// Open the recordset
rs.Open(CRecordset::dynaset, NULL, CRecordset::useMultiRowFetch);
// Move to the first record in the recordset
rs.MoveFirst();
// Move to the sixth record
rs.Move(5);
// Other equivalent ways to move to the sixth record:
rs.Move(6, SQL_FETCH_ABSOLUTE);
rs.SetAbsolutePosition(6);
// In this case, the sixth record is the first record in the next rowset,
// so the following are also equivalent:
rs.MoveFirst();
rs.Move(1, SQL_FETCH_NEXT);
rs.MoveFirst();
rs.MoveNext();
CRecordset::MoveFirst
使第一行集中的第一条记录成为当前记录。
void MoveFirst();
无论是否实现了批量行提取,这始终是记录集中的第一条记录。
打开记录集后,无需立即调用 MoveFirst。 此时,第一条记录(如果有)将自动成为当前记录。
此成员函数对仅向前记录集无效。
在记录集中移动时,无法跳过已删除的记录。 有关详细信息,请参阅 IsDeleted 成员函数。
如果记录集没有记录,则调用任何 Move 函数将引发异常。 若要确定记录集是否有任何记录,请调用 IsBOF 和 IsEOF。
如果在更新或添加当前记录时调用任何 Move 函数,更新将丢失,而不会发出警告。
有关记录集导航的详细信息,请参阅文章“记录集:滚动 (ODBC)”和“记录集:书签和绝对位置 (ODBC)”。 有关批量行提取的详细信息,请参阅记录集:批量提取记录 (ODBC)。
请参阅 IsBOF 的示例。
CRecordset::MoveLast
使最后完成的行集中的第一条记录成为当前记录。
void MoveLast();
如果尚未实现批量行提取,则记录集的大小为 1,因此 MoveLast 移动到记录集中的最后一条记录。
此成员函数对仅向前记录集无效。
在记录集中移动时,无法跳过已删除的记录。 有关详细信息,请参阅 IsDeleted 成员函数。
如果记录集没有记录,则调用任何 Move 函数将引发异常。 若要确定记录集是否有任何记录,请调用 IsBOF 和 IsEOF。
如果在更新或添加当前记录时调用任何 Move 函数,更新将丢失,而不会发出警告。
有关记录集导航的详细信息,请参阅文章“记录集:滚动 (ODBC)”和“记录集:书签和绝对位置 (ODBC)”。 有关批量行提取的详细信息,请参阅记录集:批量提取记录 (ODBC)。
请参阅 IsBOF 的示例。
CRecordset::MoveNext
使下一行集中的第一条记录成为当前记录。
void MoveNext();
如果尚未实现批量行提取,则记录集的大小为 1,因此 MoveNext 移动到下一条记录。
在记录集中移动时,无法跳过已删除的记录。 有关详细信息,请参阅 IsDeleted 成员函数。
如果记录集没有记录,则调用任何 Move 函数将引发异常。 若要确定记录集是否有任何记录,请调用 IsBOF 和 IsEOF。
此外,建议在调用 IsEOF 之前调用 MoveNext。 例如,如果滚动到记录集末尾,IsEOF 将返回非零值;后续调用 MoveNext 将引发异常。
如果在更新或添加当前记录时调用任何 Move 函数,更新将丢失,而不会发出警告。
有关记录集导航的详细信息,请参阅文章“记录集:滚动 (ODBC)”和“记录集:书签和绝对位置 (ODBC)”。 有关批量行提取的详细信息,请参阅记录集:批量提取记录 (ODBC)。
请参阅 IsBOF 的示例。
CRecordset::MovePrev
使前一行集中的第一条记录成为当前记录。
void MovePrev();
如果尚未实现批量行提取,则记录集的大小为 1,因此 MovePrev 移动到上一条记录。
此成员函数对仅向前记录集无效。
在记录集中移动时,无法跳过已删除的记录。 有关详细信息,请参阅 IsDeleted 成员函数。
如果记录集没有记录,则调用任何 Move 函数将引发异常。 若要确定记录集是否有任何记录,请调用 IsBOF 和 IsEOF。
此外,建议在调用 IsBOF 之前调用 MovePrev。 例如,如果滚动到记录集开头,IsBOF 将返回非零值;后续调用 MovePrev 将引发异常。
如果在更新或添加当前记录时调用任何 Move 函数,更新将丢失,而不会发出警告。
有关记录集导航的详细信息,请参阅文章“记录集:滚动 (ODBC)”和“记录集:书签和绝对位置 (ODBC)”。 有关批量行提取的详细信息,请参阅记录集:批量提取记录 (ODBC)。
请参阅 IsBOF 的示例。
CRecordset::OnSetOptions
调用以为指定 ODBC 语句设置选项(在选择时使用)。
virtual void OnSetOptions(HSTMT hstmt);
hstmt
要设置其选项的 ODBC 语句的 HSTMT。
调用 OnSetOptions 以为指定 ODBC 语句设置选项(在选择时使用)。 框架调用此成员函数,以设置记录集的初始选项。
OnSetOptions 确定数据源对可滚动游标和游标并发的支持,并相应地设置记录集选项。 (OnSetOptions 用于选择操作,OnSetUpdateOptions 则用于更新操作。)
重写 OnSetOptions 以设置特定于驱动程序或数据源的选项。 例如,如果数据源支持打开供独占访问,则可以重写 OnSetOptions 以利用此功能。
有关游标的详细信息,请参阅 ODBC。
CRecordset::OnSetUpdateOptions
调用以为指定 ODBC 语句设置选项(在更新时使用)。
virtual void OnSetUpdateOptions(HSTMT hstmt);
hstmt
要设置其选项的 ODBC 语句的 HSTMT。
调用 OnSetUpdateOptions,为指定 ODBC 语句设置选项(在更新时使用)。 框架在创建 HSTMT 以更新记录集中的记录后调用此成员函数。 (OnSetOptions 用于选择操作,OnSetUpdateOptions 则用于更新操作。)OnSetUpdateOptions 确定数据源对可滚动游标和游标并发性的支持,并相应地设置记录集选项。
重写 OnSetUpdateOptions 以在使用该语句访问数据库之前设置 ODBC 语句选项。
有关游标的详细信息,请参阅 ODBC。
CRecordset::Open
通过检索表或执行记录集所表示的查询来打开记录集。
virtual BOOL Open(
UINT nOpenType = AFX_DB_USE_DEFAULT_TYPE,
LPCTSTR lpszSQL = NULL,
DWORD dwOptions = none);
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 CDaoRecordset 进行交互。
有关这些记录集类型的详细信息,请参阅记录集 (ODBC) 。 相关信息请参阅 Windows SDK 中的“使用块和可滚动游标”。
如果请求的类型不受支持,框架将引发异常。
lpszSQL
包含下列项之一的字符串指针:
一个 NULL 指针。
表的名称。
SQL SELECT 语句(SQL WHERE 或 ORDER BY 子句可选)。
一个 CALL 语句,指定预定义查询的名称(存储过程)。 请注意不要在大括号和 CALL 关键字之间插入空格。
有关此字符串的详细信息,请参阅注解部分下有关 ClassWizard 角色的表和讨论。
结果集中列的顺序必须与 DoFieldExchange 或 DoBulkFieldExchange 函数替代中 RFX 或批量 RFX 函数调用的顺序匹配。
dwOptions
位掩码,可以指定下面列出的值的组合。 其中一些是互斥的。 默认值为 none。
CRecordset::none 未设置任何选项。 此参数值与所有其他值互斥。 默认情况下,可以使用 Edit 或 Delete 更新记录集,并允许使用 AddNew 来追加新记录。 可更新性取决于数据源和指定的 nOpenType 选项。 批量添加的优化不可用。 不会实现批量行提取。 记录集导航期间不会跳过已删除的记录。 书签不可用。 实现自动脏字段检查。
CRecordset::appendOnly 不允许记录集上有 Edit 或 Delete。 仅允许 AddNew。 此选项与 CRecordset::readOnly 互斥。
CRecordset::readOnly 将记录集打开为只读。 此选项与 CRecordset::appendOnly 互斥。
CRecordset::optimizeBulkAdd 使用准备好的 SQL 语句一次优化添加多个记录。 仅当未使用 ODBC API 函数 SQLSetPos 更新记录集时才适用。 第一次更新确定哪些字段标记为脏。 此选项与 CRecordset::useMultiRowFetch 互斥。
CRecordset::useMultiRowFetch 实现批量行提取,以允许在单个提取操作中检索多个行。 这是一项旨在提高性能的高级功能;但是,ClassWizard 不支持批量记录字段交换。 此选项与 CRecordset::optimizeBulkAdd 互斥。 如果指定 CRecordset::useMultiRowFetch,则选项 CRecordset::noDirtyFieldCheck 将自动打开(双缓冲将不可用);在仅向前记录集上,选项 CRecordset::useExtendedFetch 将自动打开。 有关批量行提取的详细信息,请参阅记录集:批量提取记录 (ODBC)。
CRecordset::skipDeletedRecords 浏览记录集时跳过所有已删除的记录。 这将降低某些相对提取的性能。 此选项对仅向前记录集无效。 如果在 MovenRows 参数设置为 0 时调用 ,并且设置了 CRecordset::skipDeletedRecords 选项,那么 Move 将断言。
CRecordset::skipDeletedRecords 类似于驱动程序打包,这意味着从记录集中删除已删除的行。 但是,如果驱动程序打包记录,则只会跳过删除的那些记录;打开记录集时,不会跳过其他用户删除的记录。
CRecordset::skipDeletedRecords 将跳过其他用户删除的行。
CRecordset::useBookmarks 可以在记录集上使用书签(如果支持)。 书签会减缓数据检索速度,但提高了数据导航的性能。 对仅向前记录集无效。 有关详细信息,请参阅记录集:书签和绝对位置 (ODBC)。
CRecordset::noDirtyFieldCheck 关闭自动脏字段检查(双缓冲)。 这将提高性能;但是,必须通过调用 SetFieldDirty 和 SetFieldNull 成员函数手动将字段标记为脏。
CRecordset 类中的双缓冲类似于 CDaoRecordset 类中的双缓冲。 但是,在 CRecordset 中,不能对单个字段启用双缓存;你可以为所有字段启用它,也可以为所有字段禁用它。 如果指定选项 CRecordset::useMultiRowFetch,则 CRecordset::noDirtyFieldCheck 会自动打开;但是,SetFieldDirty 和 SetFieldNull 不能在实现批量行提取的记录集上使用。
CRecordset::executeDirect 请勿使用准备好的 SQL 语句。 为了提高性能,如果永远不会调用 Requery 成员函数,请指定此选项。
CRecordset::useExtendedFetch 实现 SQLExtendedFetch 而不是 SQLFetch。 这是针对仅向前记录集实现批量行提取而设计的。 如果在仅向前记录集上指定选项 CRecordset::useMultiRowFetch,则 CRecordset::useExtendedFetch 会自动打开。
CRecordset::userAllocMultiRowBuffers 用户将为数据分配存储缓冲区。 如果要分配自己的存储,可以对 CRecordset::useMultiRowFetch 使用此选项。 否则,框架将自动分配所需的存储。 有关详细信息,请参阅记录集:批量提取记录 (ODBC)。 指定 CRecordset::userAllocMultiRowBuffers 而不指定 CRecordset::useMultiRowFetch 会导致断言失败。
如果 CRecordset 成功打开对象,则为非零值;如果 CDatabase::Open(如已调用)返回 0,则为 0。
必须调用此成员函数以运行记录集定义的查询。 在调用 Open 之前,必须构造记录集对象。
此记录集与数据源的连接取决于在调用 Open 之前如何构造记录集。 如果将对象 CDatabase 传递给尚未连接到数据源的记录集构造函数,则此成员函数将使用 GetDefaultConnect 尝试打开数据库对象。 如果将 NULL 传递给记录集构造函数,则构造函数会为你构造一个 CDatabase 对象,并且 Open 会尝试连接数据库对象。 有关在这些不同情况下关闭记录集和连接的详细信息,请参阅 Close。
始终共享通过 CRecordset 对象访问数据源。 与 CDaoRecordset 类不同,不能使用 CRecordset 对象打开供独占访问的数据源。
调用 Open 时,查询(通常是 SQL SELECT 语句)会根据下表所示的条件选择记录。
不要在 SQL 字符串中插入额外的空格。 例如,如果在大括号和 CALL 关键字之间插入空格,MFC 会将 SQL 字符串错误解释为表名并将其合并到 SELECT 语句,这将导致引发异常。 同样,如果预定义查询使用输出参数,请不要在大括号和 '' 符号之间插入空格。 最后,不得在 CALL 语句的大括号或 SELECT 语句的 SELECT 关键字前插入空格。
通常的过程是将 NULL 传递给 Open;在这种情况下,Open 调用 GetDefaultSQL。 如果使用的是派生 CRecordset 类,GetDefaultSQL 将给出在 ClassWizard 中指定的表名。 可以改为在 lpszSQL 参数中指定其他信息。
无论传递什么,Open 都会为查询构造最终的 SQL 字符串(该字符串可能将 SQL WHERE 和 ORDER BY 子句追加到传递的 lpszSQL 的字符串),然后执行查询。 可以通过调用 GetSQL 后调用 Open 来检查构造的字符串。 有关记录集如何构造 SQL 语句和选择记录的更多详细信息,请参阅记录集:记录集如何选择记录 (ODBC)。
记录集类的字段数据成员绑定到所选数据列。 如果返回任何记录,则第一条记录将成为当前记录。
如果要为记录集(如筛选器或排序)设置选项,请在构造记录集对象之后但在调用 Open 之前指定这些选项。 如果要在记录集打开后刷新记录集中的记录,请调用 Requery。
有关详细信息(包括更多示例),请参阅记录集 (ODBC)、记录集:记录集如何选择记录集 (ODBC),以及记录集:创建和关闭记录集 (ODBC)。
下面的代码示例显示了不同形式的 Open 调用。
// rsSnap, rsLName, and rsDefault are CRecordset or CRecordset-derived
// objects
// Open rs using the default SQL statement, implement bookmarks, and turn
// off automatic dirty field checking
rsSnap.Open(CRecordset::snapshot, NULL, CRecordset::useBookmarks |
CRecordset::noDirtyFieldCheck);
// Pass a complete SELECT statement and open as a dynaset
rsLName.Open(CRecordset::dynaset, _T("Select L_Name from Customer"));
// Accept all defaults
rsDefault.Open();
CRecordset::RefreshRowset
更新当前行集中行的数据和状态。
void RefreshRowset(
WORD wRow,
WORD wLockType = SQL_LOCK_NO_CHANGE);
行在当前行集中基于 1 的位置。 此值的范围可以是 0 到行集的大小。
wLockType
该值指示如何在刷新行后锁定该行。 有关详细信息,请参阅“备注”。
如果为 wRow 传递的值为零,则将刷新行集中的每一行。
若要使用 RefreshRowset,必须通过在 CRecordset::useMulitRowFetch 成员函数中指定 Open 选项来实现批量行提取。
RefreshRowset 调用 ODBC API 函数 SQLSetPos。
wLockType 参数指定执行 SQLSetPos 后行的锁定状态。 下表描述了 wLockType 可能的值。
wLockType
有关 SQLSetPos 的详细信息,请参阅 Windows SDK。 有关批量行提取的详细信息,请参阅记录集:批量提取记录 (ODBC)。
CRecordset::Requery
重新生成(刷新)记录集。
virtual BOOL Requery();
如果记录集已成功重新生成,则为非零值;否则为 0。
如果返回任何记录,则第一条记录将成为当前记录。
为了使记录集反映你或其他用户对数据源进行的添加和删除,必须通过调用 Requery 重新生成记录集。 如果记录集是动态集,它会自动反映你或其他用户对其现有记录所做的更新(但不是添加)。 如果记录集是快照,则必须调用 Requery 来反映其他用户的编辑以及添加和删除。
对于动态集或快照,如果希望使用新筛选器或排序或新参数值重新生成记录集,请调用 Requery。 通过在调用 m_strFilter 之前将新值分配给 m_strSort 和 Requery,设置新的筛选器或排序属性。 通过在调用 Requery 之前将新值分配给参数数据成员来设置新参数。 如果筛选器和排序字符串保持不变,则可以重复使用查询,从而提高性能。
如果尝试重新生成记录集失败,则会关闭记录集。 在调用 Requery 之前,可以通过调用 CanRestart 成员函数来确定是否可以重新查询记录集。
CanRestart 不保证 Requery 成功。
仅在调用 Requery 后调用 Open。
本示例重新生成记录集以应用不同的排序顺序。
CCustomer rsCustSet(&m_dbCust);
// Open the recordset
rsCustSet.Open();
// Use the recordset ...
// Set the sort order and Requery the recordset
rsCustSet.m_strSort = _T("L_Name, ContactFirstName");
if (!rsCustSet.CanRestart())
return; // Unable to requery
if (!rsCustSet.Requery())
// Requery failed, so take action
AfxMessageBox(_T("Requery failed!"));
CRecordset::SetAbsolutePosition
将记录集放置在对应于指定记录编号的记录上。
void SetAbsolutePosition(long nRows);
nRows
记录集中当前记录的基于 1 的序号位置。
SetAbsolutePosition 根据此序号位置移动当前记录指针。
此成员函数对仅前进记录集无效。
对于 ODBC 记录集,绝对位置设置为 1 表示记录集中的第一条记录;设置为 0 表示文件开头 (BOF) 位置。
还可以将负值传递给 SetAbsolutePosition。 在这种情况下,记录集的位置从记录集末尾开始计算。 例如,SetAbsolutePosition( -1 ) 将当前记录指针移动到记录集中的最后一条记录。
绝对位置不应用作代理项记录编号。 书签仍然是保留并返回到给定位置的建议方法,因为删除前一条记录时记录的位置会改变。 此外,如果再次重新创建记录集,则无法确保给定记录集具有相同的绝对位置,因为不能保证记录集中各个记录的顺序,除非使用 ORDER BY 子句通过 SQL 语句创建记录集。
有关记录集导航和书签的详细信息,请参阅记录集:滚动 (ODBC) 和记录集:书签和绝对位置 (ODBC)。
CRecordset::SetBookmark
将记录集放置在包含指定书签的记录上。
void SetBookmark(const CDBVariant& varBookmark);
varBookmark
对包含特定记录书签值的 CDBVariant 对象的引用。
若要确定记录集是否支持书签,请调用 CanBookmark。 若要使书签可用(如果受支持),必须在 CRecordset::useBookmarks 成员函数的 dwOptions 参数中设置 Open 选项。
如果书签不受支持或不可用,则调用 SetBookmark 将导致引发异常。 仅向前记录集不支持书签。
若要首先检索当前记录的书签,请调用 GetBookmark,它将书签值保存到 CDBVariant 对象。 稍后,可以通过调用 SetBookmark 使用已保存的书签值返回到该记录。
执行某些记录集操作后,应在调用 SetBookmark 之前检查书签持久性。 例如,如果检索带有 GetBookmark 的书签,然后调用 Requery,则该书签可能不再有效。 调用 CDatabase::GetBookmarkPersistence,以检查是否可以安全调用 SetBookmark。
有关书签和记录集导航的详细信息,请参阅记录集:书签和绝对位置 (ODBC) 和记录集:滚动 (ODBC)。
CRecordset::SetFieldDirty
将记录集的字段数据成员标记为已更改或未更改。
void SetFieldDirty(void* pv, BOOL bDirty = TRUE);
包含记录集中或 NULL 中的字段数据成员的地址。 如果为 NULL,则会标记记录集中的所有字段数据成员。 (C++ NULL 与数据库术语中的 Null 不同,后者意味着“没有值”。)
bDirty
如果字段数据成员标记为“脏”(已更改),则为 TRUE。 如果字段数据成员标记为“干净”(未更改),则为 FALSE。
将字段标记为未更改可确保字段未更新,并导致 SQL 流量减少。
此成员函数不适用于使用批量行提取的记录集。 如果已实现批量行提取,则 SetFieldDirty 将导致断言失败。 有关批量行提取的详细信息,请参阅记录集:批量提取记录 (ODBC)。
框架标记更改的字段数据成员,以确保它们通过记录字段交换 (RFX) 机制写入到数据源中的记录。 更改字段的值通常会自动将字段设置为“脏”,因此很少需要自行调用 SetFieldDirty,但有时你可能希望确保无论字段数据成员中的值是什么,都会显式更新或插入列。
仅在调用 Edit 或 AddNew 后调用此成员函数。
对函数的第一个参数使用 NULL 会将函数仅应用于 outputColumn 字段,而不是 param 字段。 例如,调用
SetFieldNull(NULL);
仅将 outputColumn 字段设置为 NULL;param 字段不受影响。
若要处理 param 字段,必须提供要处理的单个 param 的实际地址,例如:
SetFieldNull(&m_strParam);
这意味着你不能像设置 param 字段那样将所有 NULL 字段设置为 outputColumn。
CRecordset::SetFieldNull
将记录集的字段数据成员标记为 Null(特别是没有值)或非 Null。
void SetFieldNull(void* pv, BOOL bNull = TRUE);
包含记录集中或 NULL 中的字段数据成员的地址。 如果为 NULL,则会标记记录集中的所有字段数据成员。 (C++ NULL 与数据库术语中的 Null 不同,后者意味着“没有值”。)
bNull
如果将字段数据成员标记为没有值 (Null),则为非零值。 如果字段数据成员标记为“非 Null”,则为 0。
向记录集添加新记录时,所有字段数据成员最初都设置为 Null 值,并标记为“脏”(已更改)。 从数据源检索记录时,其列已有值或为 Null。
不要对正在使用批量行提取的记录集调用此成员函数。 如果已实现批量行提取,那么调用 SetFieldNull 将导致断言失败。 有关批量行提取的详细信息,请参阅记录集:批量提取记录 (ODBC)。
如果特别希望将当前记录的字段指定为没有值,则调用 SetFieldNull,同时将 bNull 设置为 TRUE,将其标记为 Null。 如果字段之前标记为 Null,并且现在想要为其指定一个值,请设置其新值。 无需使用 SetFieldNull 删除 Null 标记。 若要确定是否允许字段为 Null,请调用 IsFieldNullable。
仅在调用 Edit 或 AddNew 后调用此成员函数。
对函数的第一个参数使用 NULL 会将函数仅应用于 outputColumn 字段,而不是 param 字段。 例如,调用
SetFieldNull(NULL);
仅将 outputColumn 字段设置为 NULL;param 字段不受影响。
若要处理 param 字段,必须提供要处理的单个 param 的实际地址,例如:
SetFieldNull(&m_strParam);
这意味着你不能像设置 param 字段那样将所有 NULL 字段设置为 outputColumn。
将参数设置为 Null 时,在打开记录集之前调用 SetFieldNull 将导致断言。 在这种情况下,调用 SetParamNull。
SetFieldNull 通过 DoFieldExchange 实现。
CRecordset::SetLockingMode
将锁定模式设置为“乐观”锁定(默认)或“悲观”锁定。 确定如何锁定记录以进行更新。
void SetLockingMode(UINT nMode);
nMode
包含 enum LockMode 中的以下值之一:
optimistic 乐观锁定将仅锁定在调用 Update 期间更新的记录。
pessimistic 悲观锁定在调用 Edit 时立即锁定该记录,并保持锁定状态,直到 Update 调用完成或移至新记录。
如果需要指定记录集用于更新的两种记录锁定策略中的一种,请调用此成员函数。 默认情况下,记录集的锁定模式为 optimistic。 可以将此更改为更谨慎的 pessimistic 锁定策略。 在构造并打开记录集对象之后且调用 SetLockingMode 之前调用 Edit。
CRecordset::SetParamNull
将参数标记为 Null(特别是没有值)或非 Null。
void SetParamNull(
int nIndex,
BOOL bNull = TRUE);
nIndex
参数的从零开始的索引。
bNull
如果为 TRUE(默认值),则该参数将标记为 Null。 否则,参数将标记为非 Null。
与 SetFieldNull 不同,可以在打开记录集之前调用 SetParamNull。
SetParamNull 通常与预定义查询一起使用(存储过程)。
CRecordset::SetRowsetCursorPosition
将光标移动到当前行集中的行。
void SetRowsetCursorPosition(WORD wRow, WORD wLockType = SQL_LOCK_NO_CHANGE);
行在当前行集中基于 1 的位置。 此值的范围可以是 1 到行集的大小。
wLockType
该值指示如何在刷新行后锁定该行。 有关详细信息,请参阅“备注”。
实现批量行提取时,将按行集检索记录,其中所提取的行集中的第一条记录为当前记录。 若要在行集中创建另一条记录,请调用 SetRowsetCursorPosition。 例如,可以将 SetRowsetCursorPosition 与 GetFieldValue 成员函数结合使用,以从记录集的任何记录动态检索数据。
若要使用 SetRowsetCursorPosition,必须通过在 CRecordset::useMultiRowFetch 成员函数中指定 dwOptions 参数的 Open 选项来实现批量行提取。
SetRowsetCursorPosition 调用 ODBC API 函数 SQLSetPos。
wLockType 参数指定执行 SQLSetPos 后行的锁定状态。 下表描述了 wLockType 可能的值。
wLockType
有关 SQLSetPos 的详细信息,请参阅 Windows SDK。 有关批量行提取的详细信息,请参阅记录集:批量提取记录 (ODBC)。
CRecordset::SetRowsetSize
指定希望在提取期间检索的记录数。
virtual void SetRowsetSize(DWORD dwNewRowsetSize);
dwNewRowsetSize
在给定提取期间要检索的行数。
此虚拟成员函数指定在使用批量行提取时在单个提取期间要检索的行数。 要实现批量行提取,必须在 CRecordset::useMultiRowFetch 成员函数的 dwOptions 参数中设置 Open 选项。
在不实现批量行提取的情况下调用 SetRowsetSize 将导致断言失败。
在调用 SetRowsetSize 之前调用 Open 以最初设置记录集的行集大小。 实现大容量行提取时的默认行集大小为 25。
调用 SetRowsetSize 时要谨慎使用。 如果手动为数据分配存储(由 CRecordset::userAllocMultiRowBuffers 中 dwOptions 参数的 Open 选项指定),则应在调用 SetRowsetSize 之后且执行任何游标导航操作之前,检查是否需要重新分配这些存储缓冲区。
若要获取行集大小的当前设置,请调用 GetRowsetSize。
有关批量行提取的详细信息,请参阅记录集:批量提取记录 (ODBC)。
CRecordset::Update
通过在数据源上保存新数据或编辑的数据来完成 AddNew 或 Edit 操作。
virtual BOOL Update();
如果成功更新了一条记录,那么为非零值;如果未更改任何列,则为 0。 如果未更新任何记录,或者更新了多个记录,则会引发异常。 对于数据源上的任何其他故障,也会引发异常。
调用 AddNew 或 Edit 成员函数后调用此成员函数。 完成 AddNew 或 Edit 操作需要进行此调用。
如果已实现批量行提取,则无法调用 Update。 这将导致断言失败。 虽然类 CRecordset 不提供更新批量数据行的机制,但你可以使用 ODBC API 函数 SQLSetPos 编写自己的函数。 有关批量行提取的详细信息,请参阅记录集:批量提取记录 (ODBC)。
AddNew 和 Edit 都准备了一个编辑缓冲区,在其中放置添加或编辑的数据,以便保存到数据源。
Update 保存数据。 仅更新标记为或检测到“已更改”的字段。
如果数据源支持事务,则可以调用 Update(及其相应的 AddNew 或 Edit 调用)作为事务的一部分。 有关事务的详细信息,请参阅事务 (ODBC)。
如果调用 Update 时没有事先调用 AddNew 或 Edit,则 Update 将引发 CDBException。 如果调用 AddNew 或 Edit,则必须在调用 Update 操作之前,或者关闭记录集或数据源连接之前调用 Move。 否则,更改会丢失且没有通知。
有关处理 Update 失败的详细信息,请参阅记录集:记录集如何更新记录 (ODBC)。
请参阅事务:在记录集中执行事务 (ODBC)。
CObject 类
层次结构图
CDatabase 类
CRecordView 类