使用记录集

Recordset 对象具有内置功能,使你可以重新排列结果集中数据的顺序,根据提供的条件搜索特定记录,甚至使用索引优化这些搜索操作。 这些功能是否可供使用取决于提供程序,在某些情况下(例如 Index 属性的情况)取决于数据源本身的结构。

排列数据

通常,对 Recordset 中的数据进行排序的最有效方法是在用于向其返回结果的 SQL 命令中指定 ORDER BY 子句。 但是,可能需要更改已创建的 Recordset 中的数据的顺序。 可以使用 Sort 属性建立遍历 Recordset 的行的顺序。 此外,Filter 属性确定遍历行时可以访问的行。

Sort 属性设置或返回一个 String 值,该值指示 Recordset 中要排序的字段名称。 每个名称都用逗号分隔,可以选择后跟空白和关键字 ASC(按升序对字段进行排序)或 DESC(按降序对字段进行排序)。 默认情况下,如果未指定关键字,则字段按升序排序。

排序操作效率高,因为数据不是以物理方式重新排列,而是按照索引指定的顺序进行访问。

Sort 属性要求 CursorLocation 属性设置为 adUseClient。 如果索引尚不存在,将为 Sort 属性中指定的每个字段创建临时索引。

将 Sort 属性设置为空字符串会将行重置为其原始顺序并删除临时索引。 不会删除现有索引。

假设 Recordset 包含名为 firstName、middleInitial 和 lastName 的三个字段。 将 Sort 属性设置为字符串“lastName DESC, firstName ASC”,它将按姓氏降序然后名字升序对 Recordset 进行排序。 中间名首字母将被忽略。

排序条件字符串中引用的字段不能命名为“ASC”或“DESC”,因为这些名称与关键字 ASC 和 DESC 冲突。 在返回 Recordset 的查询中使用 AS 关键字,为具有冲突名称的字段提供别名。

有关 Recordset 筛选的详细信息,请参阅本主题后面的“筛选结果”。

查找特定记录

ADO 提供 FindSeek 方法,用于查找 Recordset 中的特定记录。 Find 方法受各种提供程序支持,但仅限于单个搜索条件。 Seek 方法支持搜索多个条件,但许多提供程序不支持。

字段上的索引可以大大增强 Recordset 对象的 Find 方法以及 Sort 和 Filter 属性的性能。 可以通过设置动态 Optimize 属性为 Field 对象创建内部索引。 将 CursorLocation 属性设置为 adUseClient 时,此动态属性将添加到 Field 对象的 Properties 集合中。 请记住,此索引是 ADO 的内部索引 - 你无法访问它或将其用于任何其他目的。 此外,此索引不同于 Recordset 对象的 Index 属性。

Find 方法可快速在 Recordset 的列(字段)中找到值。 通常可以使用 Optimize 属性在列上创建索引来提高列上 Find 方法的速度。

Find 方法将搜索限制为一个字段的内容。 Seek 方法要求你具有索引并具有其他限制。 如果必须在不是索引基础的多个字段上进行搜索,或者提供程序不支持索引,则可以使用 Recordset 对象的 Filter 属性来限制结果。

查找

Find 方法在 Recordset 中搜索符合指定条件的行。 (可选)可以指定搜索方向、起始行和起始行的偏移量。 如果满足条件,则会在找到的记录上设置当前行位置;否则,位置设置为 Recordset 的末尾(或开始),具体取决于搜索方向。

只能为条件指定单列名称。 换句话说,此方法不支持多列搜索。

条件的比较运算符可以是“>(大于)、“<(小于)、“=”(等于)、“>=”(大于或等于)、“<=”(小于或等于)、“<>(不等于)或“LIKE”(模式匹配)。

条件值可以是字符串、浮点数或日期。 字符串值用单引号或“#”(数字符号)标记分隔(例如“state = 'WA'”或“state = #WA#”)。 日期值用“#”(数字符号)标记分隔(例如“start_date > #7/22/97#”)。

如果比较运算符为“like”,则字符串值可以包含星号 (*) 来查找任何字符或子字符串的一个或多个匹配项。 例如,“state like 'M*'”与 Maine 和 Massachusetts 匹配。 还可以使用前导星号和尾随星号查找值中包含的子字符串。 例如,“state like '*as*'”与 Alaska、Arkansas 和 Massachusetts 匹配。

如前所述,星号只能在条件字符串的末尾使用或在条件字符串的开头和末尾一起使用。 不能将星号用作前导通配符 ('*str') 或嵌入通配符 ('s*r')。 这将导致错误。

Seek 和 Index

如果基础提供程序支持 Recordset 对象的索引,请使用 Seek 方法与 Index 属性。 使用 Supports(adSeek) 方法来确定基础提供程序是否支持 Seek,使用 Supports(adIndex) 方法来确定提供程序是否支持索引。 (例如,Microsoft Jet 的 OLE DB 提供程序支持 Seek 和 Index。)

如果 Seek 找不到所需的行,不会发生错误,该行位于 Recordset 的末尾。 在执行此方法之前,将 Index 属性设置为所需的索引。

此方法仅支持服务器端游标。 当 Recordset 对象的 CursorLocation 属性值为 adUseClient 时,不支持 Seek。

只有在使用 adCmdTableDirect 的 CommandTypeEnum 值打开 Recordset 对象时,才能使用此方法。

筛选结果

Find 方法将搜索限制为一个字段的内容。 Seek 方法要求你具有索引并具有其他限制。 如果必须在不是索引基础的多个字段上进行搜索,或者提供程序不支持索引,则可以使用 Recordset 对象的 Filter 属性来限制结果。

使用 Filter 属性选择性地筛选 Recordset 对象中的记录。 筛选后的 Recordset 成为当前游标,这意味着在删除 Filter 之前,不满足 Filter 条件的记录在 Recordset 中不可用。 基于当前游标返回值的其他属性会受到影响,例如 AbsolutePosition、AbsolutePage、RecordCount 和 PageCount。 这是因为将 Filter 属性设置为特定值会将当前记录移动到满足新值的第一条记录。

Filter 属性采用变量参数。 此值表示使用 Filter 属性的三种方法之一:条件字符串、FilterGroupEnum 常量或书签数组。 有关详细信息,请参阅本主题后面的“使用条件字符串进行筛选”、“使用常量进行筛选”和“使用书签进行筛选”。

注意

当知道要选择的数据时,使用有效筛选结果集的 SQL 语句(而不是依赖 Filter 属性)打开 Recordset 通常更高效。

若要从 Recordset 中删除筛选器,请使用 adFilterNone 常量。 将 Filter 属性设置为零长度字符串 ("") 的效果与使用 adFilterNone 常量的效果相同。

使用条件字符串进行筛选

条件字符串由 FieldName Operator Value 形式的子句组成(例如 "LastName = 'Smith'")。 可以通过使用 AND(例如 "LastName = 'Smith' AND FirstName = 'John'")和 OR(例如 "LastName = 'Smith' OR LastName = 'Jones'")连接单个子句来创建复合子句。 条件字符串应遵循以下准则:

  • FieldName 必须是 Recordset 中的有效字段名称。 如果字段名称包含空格,则必须用方括号将该名称括起来。

  • Operator 必须是下列其中一项:<><=>=<>=LIKE

  • Value 是用于比较字段值的值(例如 'Smith'#8/24/95#12.345$50.00)。 字符串使用单引号 ('),日期使用井号 (#)。 对于数字,可以使用小数点、美元符号和科学记数法。 如果 Operator 为 LIKE,则 Value 可以使用通配符。 只允许使用星号 (*) 和百分号 (%) 通配符,并且它们必须是字符串中的最后一个字符。 Value 不能为空。

    注意

    若要在筛选器 Value 中包含单引号 ('),请使用两个单引号来表示一个单引号。 例如,若要筛选 O'Malley,则条件字符串应为 "col1 = 'O''Malley'"。 若要在筛选器值的开头和末尾包含单引号,请使用井号 (#) 将该字符串括起来。 例如,若要筛选 '1',则条件字符串应为 "col1 = #'1'#"

AND 和 OR 之间没有优先级。 可以使用圆括号将子句分组。 但是,不能对 OR 联接的子句进行分组,然后使用 AND 将该组联接到另一个子句,如下所示。

(LastName = 'Smith' OR LastName = 'Jones') AND FirstName = 'John'  

可以按如下所示构造此筛选器。

(LastName = 'Smith' AND FirstName = 'John') OR (LastName = 'Jones' AND FirstName = 'John')  

在 LIKE 子句中,可以在模式的开头和末尾使用通配符(例如 LastName Like '*mit*')或仅在模式的末尾使用通配符(例如 LastName Like 'Smit*')。

使用常量进行筛选

以下常量可用于筛选 Recordset。

返回的常量 说明
adFilterAffectedRecords 筛选器仅查看受上次 Delete、Resync、UpdateBatch 或 CancelBatch 调用影响的记录。
adFilterConflictingRecords 筛选器查看上次批量更新失败的记录。
adFilterFetchedRecords 筛选器查看当前缓存中的记录,即上次调用从数据库中检索记录的结果。
adFilterNone 删除当前筛选器并还原所有记录以供查看。
adFilterPendingRecords 筛选器仅查看已更改但尚未发送到服务器的记录。 仅适用于批量更新模式。

例如,通过筛选器常量你可以仅查看在上次 UpdateBatch 方法调用期间受影响的记录,从而更轻松地解决批量更新模式期间的单个记录冲突,如以下示例所示。

Attribute VB_Name = "modExaminingData"

使用书签进行筛选

最后,可以将书签的变量数组传递给 Filter 属性。 生成的游标将仅包含其书签传递到属性的记录。 下面的代码示例从 Recordset 中的记录中创建书签数组,该 Recordset 在 ProductName 字段中有一个“B”。 然后,它将数组传递到 Filter 属性,并显示有关最终筛选的 Recordset 的信息。

'BeginFilterBkmk  
Dim vBkmkArray() As Variant  
Dim i As Integer  
  
'Recordset created using "SELECT * FROM Products" as command.  
'So, we will check to see if ProductName has a capital B, and  
'if so, add to the array.  
i = 0  
Do While Not objRs.EOF  
    If InStr(1, objRs("ProductName"), "B") Then  
        ReDim Preserve vBkmkArray(i)  
        vBkmkArray(i) = objRs.Bookmark  
        i = i + 1  
        Debug.Print objRs("ProductName")  
    End If  
    objRs.MoveNext  
Loop  
  
'Filter using the array of bookmarks.  
objRs.Filter = vBkmkArray  
  
objRs.MoveFirst  
Do While Not objRs.EOF  
    Debug.Print objRs("ProductName")  
    objRs.MoveNext  
Loop  
'EndFilterBkmk  

创建 Recordset 的克隆

使用 Clone 方法创建多个重复的 Recordset 对象,尤其是需要在给定的记录集中维护多条当前记录时。 与创建并打开使用与原始定义相同的新 Recordset 对象相比,使用 Clone 方法更有效。

新创建的克隆的当前记录最初设置为第一条记录。 克隆的 Recordset 中的当前记录指针不会与原始记录指针同步,反之亦然。 可以在每个 Recordset 中独立导航。

无论游标类型如何,对一个 Recordset 对象所做的更改在其所有克隆中都可见。 但是,在原始 Recordset 上执行 Requery 后,克隆将不再同步到原始记录集。

关闭原始 Recordset 不会关闭其副本,关闭副本也不会关闭原始 Recordset 或任何其他副本。

只能克隆支持书签的 Recordset 对象。 书签值可交换;也就是说,一个 Recordset 对象的书签引用可引用在其任何克隆中相同的记录。