程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> 更多編程語言 >> Delphi >> Delphi數據庫編程新手指南(09)

Delphi數據庫編程新手指南(09)

編輯:Delphi

  數據庫應用程序最常見的任務,是根據某些規則來搜索特定的記錄。在Delphi中,ADOExpress組件實現檢索記錄的方法與BDE中的方法類似。本章將引導你學習運用各種方法來搜索和定位數據。

  注:本章涉及到的MS Access數據庫—aboutdelphi.mdb,以及核心組件(數據訪問和數據感知)的相關設置,請參考課程前些章節。下述示例將假定你的應用程序中,已有一個指向數據庫表的ADOTable組件。

  當想到搜索算法,其過程應是:從表的頂部開始,檢查每一行的某字段——看它是否符合相關條件,直到遍歷完選定的記錄或到達底行,停止循環。我們希望Delphi將這些步驟隱藏(封裝)起來。ADODataset(Table或Query)組件有幾種方法,用於檢索及定位數據集中的記錄。

定位(Locate)

此搜索方法,會把與搜索條件相匹配的當前記錄指定為第一行。通過使用Locate方法,能找到已傳遞給Variant數組的一個或多個字段的值。

下面的代碼,通過Locate方法找到第一條Name字段包含'Zoom'的記錄。如果返回值為True——表示找到記錄,並已置為當前行。


[delphi] 
AdoTable1.Locate('Name','Zoom',[]); 
{...or...} 
  
var ffield, fvalue: string; 
    opts : TLocateOptions;         
ffield := 'Name'; 
fvalue := 'zoom'; 
opts := [loCaseInsensitive]; 
if not AdoTable1.Locate(ffield,fvalue, opts) then 
  ShowMessage(fvalue + ' not found in ' +ffield); 

AdoTable1.Locate('Name','Zoom',[]);
{...or...}
 
var ffield, fvalue: string;
    opts : TLocateOptions;       
ffield := 'Name';
fvalue := 'zoom';
opts := [loCaseInsensitive];
if not AdoTable1.Locate(ffield,fvalue, opts) then
  ShowMessage(fvalue + ' not found in ' +ffield);查詢(Lookup)

Lookup不會將光標移到匹配行,只返回值。Lookup返回一個variant數組,包含從匹配行返回的指定字段的值——指定字段由一個字段名列表(分號分隔)所指定。如果沒找到匹配記錄,Lookup返回一個空的variant。

下面代碼將返回值賦給名為LookupRes的variant數組:


[delphi] 
var LookupRes: Variant; 
LookupRes :=ADOTable1.Lookup('Name', 'Zoom', 'Author; Description'); 
if not VarIsNull(LookupRes)then 
 ShowMessage(VarToStr(LookupRes[0])) //authorname 

var LookupRes: Variant;
LookupRes :=ADOTable1.Lookup('Name', 'Zoom', 'Author; Description');
if not VarIsNull(LookupRes)then
 ShowMessage(VarToStr(LookupRes[0])) //authorname
Locate和Lookup方法的一個優勢是,他們不需要表進行索引。然而,當一個表擁有索引,Locate方法會用可用的最快的方法來搜索表,因此將會使用索引。

索引(Indexing)

索引有助於更快地查找和排序記錄。可基於單個或多個字段來創建索引。多字段索引使你能夠區分第一個字段可能擁有相同值的記錄。多數情況下,你會希望對頻繁查找/排序的字段編制索引。例如,若想在Type字段中搜索特定的應用程序類型,可基於此字段創建索引,以加快搜索。

一個表的主鍵會自動為其編制索引,而數據類型為OLE對象的字段不能編制索引。注意,如果進行索引的字段中具有很多相同的值,編制索引後,檢索速度不會有顯著的提高。

索引的主要缺點,是其需要占用額外的磁盤空間;在索引列插入、刪除和更新數據,比在非索引列上操作需要更長的時間。

當使用Table組件和BDE(不是ADO)時,Delphi為我們提供了一些函數,用於搜索數據庫表中的值。如Go、GoToKey、GoToNearest、Find、FindKey,FindNearest等等(完整內容請參閱Delphi的幫助主題)。 ADO不支持這些方法,而是引入了Seek方法。

查找(Seek)

ADO數據集的Seek方法進行檢索時,需要使用索引。如果沒有指定一個索引,在用Access數據庫時,數據庫引擎將使用主鍵索引。

Seek基於當前索引查找一個(或多個)指定字段的特定值。如果Seek沒有找到所需的行且未發生錯誤,並到達了數據集的結尾行。表示搜索成功,將返回一個布爾值:如果找到一條記錄,則返回True,反之返回False。

TADOTable組件的GetIndexNames方法撷取表中現有索引的列表(例如:組合框裡的項目項)。

ADOTable1.GetIndexNames(ComboBox1.Items);

在設計期間,TADOTable組件的IndexName屬性提供上面相同的列表。該IndexFieldNames屬性可作為指定表的索引的一種替代方法。在“IndexFieldNames”中,指定表索引編制的字段名稱。

Seek方法具有以下聲明:


[delphi]
function Seek(const KeyValues: Variant; SeekOption: TSeekOption= soFirstEQ): Boolean; 

function Seek(const KeyValues: Variant; SeekOption: TSeekOption= soFirstEQ): Boolean;
·KeyValues​​是一個值為Variant的數組。一個索引包含一個或多個列,該數組中包含的值分別與對應列進行比較,。

·SeekOption指定KeyValues值與對應列​​之間的比較方式。


[plain] 
SeekOption    含義 
soFirstEQ   記錄指針定位在第一個匹配的記錄上,如果有匹配記錄的話,反之定位在該數據集的末尾; 
soLastEQ    記錄指針定位在最後一個匹配的記錄上,如果有匹配記錄的話,反之定位在該數據集的末尾; 
soAfterEQ   記錄指針定位在匹配的記錄,如果有匹配記錄的話,置於其之後。 
soAfter     記錄指針定位在匹配的記錄之後。 
soBeforeEQ  記錄指針定位在匹配的記錄,如果發現,就在相匹配的記錄會被發現。 
soBefore    記錄指針定位匹配的記錄之前會被發現。 

SeekOption    含義
soFirstEQ   記錄指針定位在第一個匹配的記錄上,如果有匹配記錄的話,反之定位在該數據集的末尾;
soLastEQ    記錄指針定位在最後一個匹配的記錄上,如果有匹配記錄的話,反之定位在該數據集的末尾;
soAfterEQ   記錄指針定位在匹配的記錄,如果有匹配記錄的話,置於其之後。
soAfter     記錄指針定位在匹配的記錄之後。
soBeforeEQ  記錄指針定位在匹配的記錄,如果發現,就在相匹配的記錄會被發現。
soBefore    記錄指針定位匹配的記錄之前會被發現。
注1:Seek方法僅支持服務器端的游標。Seek不支持CursorLocation屬性為clUseClient的數據集。使用Supports方法,以確定供應商是否在底層支持Seek。

注2:基於多個字段使用Seek方法時,各字段順序必須與表結構中的字段順序相同。否則調用失敗。

注3:不能在TADOQuery組件中調用Seek方法。

判斷是否找到了匹配記錄,我們使用BOF或EOF屬性(取決於搜索的方向)。下面代碼,在ComboBox中指定索引字段,在EDIT1中指定匹配條件。


[delphi] 
var 
strIndex: string; 
strIndex := ComboBox1.Text;//from the code above  
if ADOTable1.Supports(coSeek)then begin 
 with ADOTable1 do begin 
   Close; 
   IndexName := strIndex; 
   CursorLocation := clUseServer; 
   Open; 
   Seek (Edit1.Text, soFirstEQ); 
  end; 
  if ADOTable1.EOF then 
   ShowMessage ('Record value NOT found'); 
end 

var
strIndex: string;
strIndex := ComboBox1.Text;//from the code above
if ADOTable1.Supports(coSeek)then begin
 with ADOTable1 do begin
   Close;
   IndexName := strIndex;
   CursorLocation := clUseServer;
   Open;
   Seek (Edit1.Text, soFirstEQ);
  end;
  if ADOTable1.EOF then
   ShowMessage ('Record value NOT found');
end
 

 

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved