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
浏览记录集时跳过所有已删除的记录。 这将降低某些相对提取的性能。 此选项对仅向前记录集无效。 如果在 Move
nRows 参数设置为 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
类