使用資料錄集
Recordset 物件具有內建功能,可讓您重新排列結果集中的資料順序、根據您提供的準則搜尋特定記錄,甚至是使用索引最佳化這些搜尋作業。 這些功能是否可供使用取決於提供者,在某些情況下 (例如 Index 屬性),還會取決於資料來源本身的結構。
排列資料
通常,在用來傳回結果的 SQL 命令中指定 ORDER BY 子句,是排序 Recordset 中資料最有效率的方式。 不過,您可能必須變更已建立 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 提供 Find 和 Seek 方法,以尋找 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) 方法可判斷提供者是否支援索引 (例如,OLE DB Provider for Microsoft Jet 支援 Seek 和 Index)。
如果 Seek 找不到所需的資料列,不會發生錯誤,而且資料列會位於 Recordset 的結尾。 在執行此方法之前,請先將 Index 屬性設定為所需的索引。
此方法只能搭配伺服器端資料指標使用。 當 Recordset 物件的 CursorLocation 屬性值為 adUseClient 時,不支援 Seek。
只有當 Recordset 物件以 adCmdTableDirect 的 CommandTypeEnum 值開啟時,才能使用此方法。
篩選結果
Find 方法會限制搜尋一個欄位的內容。 Seek 方法需要您有索引,此外還有其他限制。 如果您必須搜尋多個未以索引為基礎的欄位,或者您的提供者不支援索引,您可以使用 Recordset 物件的 Filter 屬性來限制結果。
使用 Filter 屬性可選擇性地篩選出 Recordset 物件中的記錄。 經過篩選的 Recordset 會變成目前資料指標,這表示在移除 Filter 之前,不符合 Filter 準則的記錄將不會出現在 Recordset 中。 根據目前資料指標傳回值的其他屬性會受到影響,例如 AbsolutePosition、AbsolutePage、RecordCount 和 PageCount。 這是因為將 Filter 屬性設定為特定值會將目前記錄移至符合新值的第一筆記錄。
Filter 屬性接受 Variant 引數。 此值代表使用 Filter 屬性的三種方法 (準則字串、FilterGroupEnum 常數或書籤陣列) 的其中一種。 如需詳細資訊,請參閱本主題稍後的<使用準則字串進行篩選>、<使用常數進行篩選>和<使用書籤進行篩選>。
注意
當您知道想要選取的數據時,使用有效篩選結果集的 SQL 語句開啟 Recordset 通常更有效率,而不是依賴 Filter 屬性。
若要從 Recordset 移除篩選,請使用 adFilterNone 常數。 將 Filter 屬性設定為長度為零的字串 ("") 與使用 adFilterNone 常數的效果相同。
使用準則字串進行篩選
準則字串是由「欄位名稱 運算子 值」格式的子句所組成 (例如 "LastName = 'Smith'"
)。 您可以使用 AND (例如 "LastName = 'Smith' AND FirstName = 'John'"
) 和 OR (例如 "LastName = 'Smith' OR LastName = 'Jones'"
) 串連個別子句來建立複合子句。 請按照下列準則字串的指導方針進行:
「欄位名稱」必須是 Recordset 的有效欄位名稱。 如果欄位名稱包含空格,則必須以方括弧括住名稱。
「運算子」必須是下列其中一項:<、>、<=、>=、<>、= 或 LIKE。
「值」是您將用來比較欄位值的值 (例如
'Smith'
、#8/24/95#
、12.345
或$50.00
)。 請使用單引號 (') 括住字串,並使用井字號 (#
) 括住日期。 對於數字,您可以使用小數點、貨幣符號和科學記號標記法。 如果「運算子」為 LIKE,「值」可以使用萬用字元。 只允許星號 (*) 和百分比符號 (%) 萬用字元,而且這些萬元字元必須是字串中的最後一個字元。 「值」不可為 Null。注意
若要在篩選「值」中包含單引號 ('),請使用兩個單引號來代表一個。 例如,若要篩選 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"
使用書籤進行篩選
最後,您可以將書籤的 Variant 陣列傳遞至 Filter 屬性。 產生的資料指標只會包含其書籤傳入屬性的記錄。 下列程式碼範例會從 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
建立記錄集的複製品
使用 Clone 方法可建立多個重複的 Recordset 物件,特別是如果您想要在一組指定的記錄中維護多筆目前記錄。 使用 Clone 方法,比建立並開啟具有與原始版本相同定義的新 Recordset 物件更有效率。
新建立複製品的目前記錄最初會設定為第一筆記錄。 所複製 Recordset 中的目前記錄指標不會與原始版本同步,反之亦然。 您可以在每個 Recordset 中獨立瀏覽。
不論資料指標類型為何,您對一個 Recordset 物件所做的變更都會顯示在其所有複製品中。 不過,在原始 Recordset 上執行 Requery 之後,複製品將不再同步至原始版本。
關閉原始 Recordset 並不會關閉其複本,關閉複本也不會關閉原始版本或任何其他複本。
只有在 Recordset 物件支援書籤時,才能複製該物件。 書籤值可互換;也就是說,來自一個 Recordset 物件的書籤參考會參考其任何複製品中的相同記錄。