Delphi數(shù)據(jù)訪問部件的應(yīng)用及編程_第1頁
Delphi數(shù)據(jù)訪問部件的應(yīng)用及編程_第2頁
Delphi數(shù)據(jù)訪問部件的應(yīng)用及編程_第3頁
Delphi數(shù)據(jù)訪問部件的應(yīng)用及編程_第4頁
Delphi數(shù)據(jù)訪問部件的應(yīng)用及編程_第5頁
已閱讀5頁,還剩25頁未讀, 繼續(xù)免費閱讀

下載本文檔

版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請進行舉報或認(rèn)領(lǐng)

文檔簡介

1、在這一章里我們主要介紹Delphi的數(shù)據(jù)訪問部件的層次結(jié)構(gòu)、多部件之間的關(guān)系、部件的屬性、方法、事件以及各部件的應(yīng)用。這些部件包括: TSession部件 數(shù)據(jù)集部件(TTable和TQuery) TDatasource部件 字段對象TField 字段編輯器的使用 TReport部件和TBatchMove部件我們對這些部件的屬性、方法和事件進行一般性的描述,讀者在實際使用Delphi開發(fā)應(yīng)用程序時,還可以通過聯(lián)機幫助獲得有關(guān)部件更詳細(xì)的信息。15.1 Delphi數(shù)據(jù)訪問部件的層次結(jié)構(gòu)Delphi提供了強大的開發(fā)數(shù)據(jù)庫應(yīng)用程序的能力,它給用戶提供了大量的數(shù)據(jù)訪問部件。以方便程序設(shè)計人員開發(fā)數(shù)據(jù)

2、庫應(yīng)用程序。這些部件中,有些部件繼承了另一些部件的屬性、方法和事件,也就是說多部件之間存在著繼承和被繼承的關(guān)系,各部件的這種關(guān)聯(lián)便構(gòu)成了一個層次結(jié)構(gòu)圖15.1 Delphi數(shù)據(jù)訪問部件的層次結(jié)構(gòu)TSession是全局性的部件,在應(yīng)用程序運行時,它自動地建立,在設(shè)計階段和運行過程中它是一個不可見的部件。TDatabase部件是為開發(fā)客戶/服務(wù)器數(shù)據(jù)庫應(yīng)用程序時,設(shè)置登錄的數(shù)據(jù)庫的有關(guān)參數(shù)的,它在數(shù)據(jù)訪問部件頁上。TDataset部件是不可見的,TTable和TQuery部件是由它派生而來的,這兩個部件一般被稱為數(shù)據(jù)集部件,它們在數(shù)據(jù)訪問部件頁上。TDatasource部件是連接數(shù)據(jù)集部件和數(shù)據(jù)瀏

3、覽部件的橋梁,它在數(shù)據(jù)訪問部件頁上。 TFields部件對應(yīng)于數(shù)據(jù)庫表中的實際字段,它既可以在應(yīng)用程序的運行過程中動態(tài)地生成也可以在程序設(shè)計階段用字段編輯器創(chuàng)建。它是不可見的部件,在程序中我們可以通過TField部件來訪問數(shù)據(jù)庫記錄的各個字段值。15.2 Tsession部件及其應(yīng)用TSession部件一般用得較少,但它對于一些特殊的應(yīng)用是很有用的,在每一個數(shù)據(jù)庫應(yīng)用程序運行時Delphi自動地創(chuàng)建一個TSession部件。程序設(shè)計人既不能看見該部件也不能顯示地創(chuàng)建一個TSession 部件,但是我們可以在應(yīng)用程序中全局性地使用TSession部件的屬性、方法。15.2.1 TSession部

4、件的重要屬性及作用TSession部件的許多重要屬性是用于控制數(shù)據(jù)庫應(yīng)用程序與數(shù)據(jù)庫的連接的,在一個應(yīng)用程序中,可以全局性地設(shè)置TSession的有關(guān)屬性值,對與之相連接的磁盤上的數(shù)據(jù)庫進行控制。TSession部件主要有下列屬性:Database屬性:是TSession中可以進行連接的所有數(shù)據(jù)庫的數(shù)據(jù)庫名字列表,這些數(shù)據(jù)庫的名字常常是實際數(shù)據(jù)庫的別名,包括數(shù)據(jù)庫的路徑、用戶名、用戶登錄口令等參數(shù)。 DatabaseCount屬性:是TSession中可以進行連接的所有數(shù)據(jù)庫的數(shù)量,它是一個整數(shù)。 KeepCounnections屬性:是一個布爾型屬性,用它說明應(yīng)用程序是否保持與一個非活動數(shù)據(jù)

5、庫的連接。因為對于一個數(shù)據(jù)庫,當(dāng)該數(shù)據(jù)庫中沒有相應(yīng)的數(shù)據(jù)集部件(TTable或TQuery)被打開時,該數(shù)據(jù)庫將自動地變成非活動的數(shù)據(jù)庫。缺省情況下,KeePcounnections的值是True,就是說應(yīng)用程序總是保持著與數(shù)據(jù)庫的連接,即使數(shù)據(jù)庫變成了非活動的數(shù)據(jù)庫時,也是如此。如果將KeepConnections屬性設(shè)置成False,那么當(dāng)數(shù)據(jù)庫由活動狀態(tài)變成非活動狀態(tài)時,應(yīng)用程序與該數(shù)據(jù)庫的連接也隨之中斷。NetFileDir屬性:說明BDE網(wǎng)絡(luò)控制文件的路徑名。PrivateDir屬性:說明存取臨時文件的路徑名。15.2.2 TSession部件的方法:TSession部件中的大部分方

6、法是用于向用戶提供與應(yīng)用程序相連接的數(shù)據(jù)庫的信息,如數(shù)據(jù)庫的名字及別名,數(shù)據(jù)庫中的表名以及數(shù)據(jù)庫引擎BDE的有關(guān)參數(shù)等,在設(shè)計數(shù)據(jù)庫應(yīng)用程序時,想要獲取有關(guān)數(shù)據(jù)庫的信息,調(diào)用TSession部件的下列方法,將會大大簡化程序的設(shè)計。GetAliasNames方法:調(diào)用該方法,我們可以獲得數(shù)據(jù)庫引擎BDE中定義的數(shù)據(jù)庫別名。 GetAliasParams方法:該方法主要用于獲取我們在BDE中定義數(shù)據(jù)庫別名時所說明的參數(shù)值,如BDE所在的目錄路徑以及實際名稱等。GetDatabaseNames 方法:調(diào)用該方法可以幫助我們獲得當(dāng)前應(yīng)用程序可以進行連接的所有數(shù)據(jù)庫的名字,數(shù)據(jù)庫的名字是用戶使用BDE工

7、具定義的實際數(shù)據(jù)庫的別名。GetDriverNames方法:數(shù)據(jù)庫引擎BDE可以與多種數(shù)據(jù)庫管理系統(tǒng)相連接,如客戶/服務(wù)器數(shù)據(jù)庫管理系統(tǒng)Oracle、Sybase以及本地數(shù)據(jù)庫管理系統(tǒng)dBASE,Paradox等,BDE與每一種數(shù)據(jù)庫管理系統(tǒng)進行連接時,都有相應(yīng)的驅(qū)動程序,而且這些驅(qū)動程序都可以選擇地安裝。通過調(diào)用GetDriverNames方法。我們可以獲得當(dāng)前BDE安裝的數(shù)據(jù)庫驅(qū)動程序的名字。 GetDriverParams方法:BDE的數(shù)據(jù)庫驅(qū)動程序中包含著多個參數(shù),如支持的民族語言、DBMS的版本號、文件塊大小等,對于服務(wù)器上的DBMS,還有數(shù)據(jù)庫服務(wù)器的名字等等。 GetTableN

8、ames方法:因為每一個數(shù)據(jù)庫都是由多個數(shù)據(jù)庫表組成的,我們通過說明數(shù)據(jù)庫名,然后調(diào)用GetTableNames方法,便可以獲得該數(shù)據(jù)庫中全部的數(shù)據(jù)庫表的名字。上述這些方法在調(diào)用時都需要一個字符串列表作為參數(shù),而且都返回一個字符串列表的值。 TSession部件還有一個叫DropConnections的方法用于控制應(yīng)用程序與數(shù)據(jù)庫的連接,當(dāng)調(diào)用DropConnections方法時,應(yīng)用程序與所有的數(shù)據(jù)庫的連接將會切斷。15.2.3 TSession部件應(yīng)用舉例例15.1:我們創(chuàng)建一個應(yīng)用程序,通過調(diào)用TSession有關(guān)的方法獲取當(dāng)前應(yīng)用程序可以進行連接的數(shù)據(jù)庫的名字以及獲取其中任意一個數(shù)據(jù)庫

9、中的全部數(shù)據(jù)庫表的名字。 通過TSession部件獲取數(shù)據(jù)庫的有關(guān)信息窗體中主要使用了兩個列表框,其中列表框DatabaselistBox用于顯示數(shù)據(jù)庫的名字,列表框TablelistBox用于顯示數(shù)據(jù)庫中的表名。程序運行完后數(shù)據(jù)庫的名字顯示在DatabaselistBox列表框中,當(dāng)用戶單擊DatabaselistBox列表框中的數(shù)據(jù)庫名時,該數(shù)據(jù)庫全部的數(shù)據(jù)庫表的名字將會顯示在TablelistBox列表框中。有關(guān)的程序代碼如下:unit unit31;interfaceusesSysUtils, Windows, Messages, Classes, Graphics, Controls

10、,Forms, Dialogs, StdCtrls, DB, DBTables, Buttons, ComCtrls, Tabnotbk; typeTQueryForm = class(TForm)BitBtn1: TBitBtn;DataSource1: TDataSource;Table1: TTable;GroupBox1: TGroupBox;CheckBox1: TCheckBox;CheckBox2: TCheckBox;PageControl1: TPageControl;TabSheet1: TTabSheet;Label1: TLabel;Label2: TLabel;Lab

11、el3: TLabel;ListBox1: TListBox;ListBox2: TListBox;ListBox3: TListBox;TabSheet2: TTabSheet;Memo1: TMemo;procedure FormCreate(Sender: TObject); procedure ListBox1Click(Sender: TObject); procedure ListBox2Click(Sender: TObject); end;varQueryForm: TQueryForm;implementation$R *.DFMuses RSLTFORM;procedure

12、 TQueryForm.FormCreate(Sender: TObject);beginScreen.Cursor := crHourglass; Populate the alias list with ListBox1 dobeginItems.Clear;Session.GetAliasNames(Items);end; Make sure there are aliases defined Screen.Cursor := crDefault;if ListBox1.Items.Count < 1 thenMessageDlg( 'There are no databa

13、se aliases currently defined. You ' + 'need at least one alias to use this demonstration.',mtError, mbOK, 0 );end;procedure TQueryForm.ListBox1Click(Sender: TObject);varstrValue: string; Holds the alias selected by the user bIsLocal: Boolean; Indicates whether or not an alias is local sl

14、Params: TStringList; Holds the parameters of the selected alias iCounter: Integer; An integer counter variable for loops begin Determine the alias name selected by the user with ListBox1 dostrValue := Items.StringsItemIndex; Get the names of the tables in the alias and put them in the appropriate li

15、st box, making sure the user's choices are reflected in the list. ListBox2.Items.Clear;Session.GetTableNames(strValue, alias to enumerate '', pattern to match 15.3.4 數(shù)據(jù)集中的數(shù)據(jù)維護數(shù)據(jù)集中的數(shù)據(jù)維護主要包括數(shù)據(jù)記錄的修改,插入和刪除。Delphi為數(shù)據(jù)集部件提供了相應(yīng)的方法用于其中的數(shù)據(jù)維護。這些方法如表15.所示。表15.3 Delphi用于數(shù)據(jù)維護的方法方 法 名 功 能Edit 將數(shù)據(jù)集置為編輯狀

16、態(tài)Append 投寄所有被修改的記錄,將記錄指針移到表中的最后一條記錄,且將數(shù)據(jù)集置為插入狀態(tài)Insert 投寄所有被修改的記錄將數(shù)據(jù)集置為插入狀態(tài)Post 將插入的新記錄和修改的記錄寫回磁盤上的數(shù)據(jù)庫表,即投寄,當(dāng)投寄成功時數(shù)據(jù)集回到瀏覽狀態(tài),若投寄不成功數(shù)據(jù)集仍然保持原有狀態(tài)Cancel 取消當(dāng)前的操作且將數(shù)據(jù)集置為瀏覽狀態(tài)Delete 刪除當(dāng)前記錄指針?biāo)诘挠涗浨覍?shù)據(jù)集置為瀏覽狀態(tài)AppendRecord 在表的最后插入一條新記錄,記錄的各個字段值作為AppendRecord的參數(shù)傳遞給新記錄InsertRecord 在當(dāng)前指針?biāo)谟涗浀暮竺娌迦胍粭l新記錄, 記錄的各個字段值作為Ins

17、ertRecord的參數(shù)傳遞給新記錄。SetRecords 修改當(dāng)前記錄,字段名和相應(yīng)的字段值作為SetRecords的參數(shù)Edt方法:如果應(yīng)用程序想對數(shù)據(jù)集中的數(shù)據(jù)記錄進行修改,我們必須要將數(shù)據(jù)集設(shè)置成編輯狀態(tài)。調(diào)用數(shù)據(jù)集部件的Edit方法便可以將數(shù)據(jù)集置成編輯狀態(tài),當(dāng)數(shù)據(jù)集已經(jīng)處在編輯狀態(tài)時,調(diào)用Edit方法不會產(chǎn)生作用。當(dāng)數(shù)據(jù)集處于編輯狀態(tài)時,移動記錄指針或調(diào)用post方法都可以將當(dāng)前記錄的修改寫回到磁盤數(shù)據(jù)庫表中。在程序中, Edit方法和post方法常常配合在一起使用,用于修改表中的記錄。如:Table1.Edit;Tabel1.FieldByName('CustNo'

18、;).Asstring := '1234'Table1.st;在上述這一段程序代碼中,第一行程序是將Table1置成編輯狀態(tài),第二行程序是對當(dāng)前記錄指針?biāo)诘挠涗浀腃ustNo字段的值修改成'1234',第二行程序是調(diào)用post方法將對當(dāng)前記錄的修改寫回數(shù)據(jù)庫表。Append方法和Insert 方法:這兩個方法都是將數(shù)據(jù)集部件置成插入狀態(tài),以在表中插入新記錄,Insert方法是在當(dāng)前指針位置的記錄后面插入一打新記錄,Append方法是在表的尾部插入一打新記錄,不過這要注意,無論用戶是調(diào)用Insert方法還是Append方法插入新記錄,增加記錄到一個具有索引的表中

19、時,都是按照索引順序?qū)懭肫湮恢茫簿褪钦f對于索引表格Insert方法和Append方法的作用是一樣的,Append僅適用于沒有索引的表。Insert方法和Append方法實際上是將數(shù)據(jù)集置成插入狀態(tài),并且插入一條空白記錄,要真正插入一條新記錄,我們必須在調(diào)用Insert或Append方法之后,還要給新記錄的各個字段賦值,最后調(diào)用post方法,將插入的記錄寫回數(shù)據(jù)庫表。調(diào)用這兩種方法插入新記錄的一般步驟如下:With tabe1 DOBeginInsert; 調(diào)用Insert方法,插入一條空記錄為記錄的各字段賦值Post;End;Post方法:數(shù)據(jù)集中的記錄被修改或插入新記錄時調(diào)用post方法將

20、數(shù)據(jù)集的修改寫回到數(shù)據(jù)庫表。根據(jù)數(shù)據(jù)集所處的狀態(tài)不同,post方法所產(chǎn)生的作用和效果是不一樣的: 當(dāng)數(shù)據(jù)集處于編輯狀態(tài)時,調(diào)用post方法,將當(dāng)前記錄的修改寫回數(shù)據(jù)庫表 當(dāng)數(shù)據(jù)集處于插入狀態(tài)時,調(diào)用post方法,將插入的新記錄寫回數(shù)據(jù)庫表 當(dāng)數(shù)據(jù)集處于SetKey狀態(tài)時,調(diào)用post方法,將數(shù)據(jù)集置成瀏覽狀態(tài)(Browse狀態(tài))post方法的調(diào)用既可以顯式地調(diào)用,也可以隱含地調(diào)用,當(dāng)數(shù)據(jù)集處于編輯狀態(tài)或插入狀態(tài)時,當(dāng)移動記錄指針時,Delphi會隱含地調(diào)用post方法,將將當(dāng)前記錄的修改寫回數(shù)據(jù)庫表,在程序調(diào)用Insert方法或Append方法時,也會隱含地調(diào)用Post方法,將先前的數(shù)據(jù)集的修

21、改寫回數(shù)據(jù)庫表。Delete方法:Delete方法用于刪除表中的記錄,調(diào)用Delete方法時,將會刪除表中當(dāng)前的記錄,并且自動地將記錄指針移到被刪記錄的下一條記錄,同時將數(shù)據(jù)集置成Browse狀態(tài)。 Cancel方法:Cancel方法用于取消當(dāng)前的操作,當(dāng)程序還沒有調(diào)用Post方法,將對記錄的修改寫回數(shù)據(jù)庫表時,調(diào)用Cancel方法,可以將記錄恢復(fù)到?jīng)]有修改之前的狀態(tài)。并且在調(diào)用Cancel方法時,它總是將數(shù)據(jù)集置成Browse狀態(tài)。AppendRecord方法和InsertRecord方法:這兩個方法分別與Append方法和Insert方法相似。它們都是用于在表中插入一條新記錄,但Appen

22、dRecord方法和InsertRecord方法比Append和Insert方法更簡單更方便一些,它們直接在表中插入一條新記錄,新記錄的各個字段值作為AppendRecord或InsertRecord方法的參數(shù)傳遞給新記錄并且不需顯式地調(diào)用post方法,將插入的新記錄寫回數(shù)據(jù)庫表。在給插入的新記錄賦字段值時,將由多個字段值組成的數(shù)組作為AppendRecord或InsertRecord的參數(shù),在字段值數(shù)組中可以為每一個字段提供一個值,或從左邊一列開始依次為任意多個字段賦值。也就是說,用戶可以從數(shù)據(jù)庫表的最左一列起,把許多列的值同時傳遞給InsertRecord,直到所有的字段被賦值,用戶也可以

23、省略字段序列后面的的一些字段值,InsertRecord會用空值來填充這些字段:用戶也可以對那些明確希望用空填充的字段傳遞保留字NIl。例如:如果表Country有Name,Captial,Continent,Area和Population字段,并且數(shù)據(jù)集部件Table1與它相連,下面的代碼便可以在Country表中當(dāng)前記錄的后面插入一條新記錄。Table1.InsertRecord ("中國","北京","五洲");在上述代碼中沒有為Area和population字段賦值,InsertRecord會用空值來填這兩個字段。SetRec

24、ords方法:調(diào)用該方法可以修改表中當(dāng)前記錄的多個字段的值,調(diào)用該方法之前必須將數(shù)據(jù)集部件置成編輯狀態(tài),調(diào)用該方法之后,還要調(diào)用post方法,才能真正將當(dāng)前記錄的修改寫回數(shù)據(jù)庫表。調(diào)用SetRecord方法時,被修改的字段值必須要與表中實際存在的字段名對應(yīng),并且數(shù)據(jù)類型要相匹配。例如,下面的代碼是修改上面剛剛插入的那條記錄。Table1.Edit;Tabel1.SetRecord(, , ,9600000,1200000000);Tabel1.post;這一段代碼是修改上面剛剛插入的那條記錄的Area 和Population 字段的值,而對Name,Continent和Captial字段沒有修

25、改。在數(shù)據(jù)集部件中,還有一個重要方法Abort方法,該方法是用于取消其他方法的調(diào)用的,如在插入記錄、修改記錄和刪除記錄之前,往往需要用戶確認(rèn)是否真的要執(zhí)行這種操作,此時調(diào)用Abort方法便可取消各種方法的調(diào)用,下面的代碼是在用戶刪除一條記之前,讓用戶確認(rèn)是否真的要執(zhí)行刪除操作。Tabel1.BeforeDelete(DataSet:TDataSet);If MessageDlg('真的要刪除記錄嗎?',mtConfirmation,mbyesNoCanel,0 <> mryes thenAbort; 取消刪除操作關(guān)于書簽(BookMark)操作;書簽操作主要用于在表

26、中快速地定位記錄指針,在應(yīng)用程序中常常要保存記錄指針?biāo)诘奈恢?,在進行其他處理之后,希望能快速地返回到先前指針?biāo)诘奈恢?,此時,使用書簽將顯得特別有用。有關(guān)書簽操作,Delphi提供了三個方法,它們是: GetBookMark GotoBookMark FreeBokMark這三個方法一般都是在一起使用,GetBookMark方法返回一個TBookMark類型的變量,該變量包含著指向當(dāng)前記錄的指針,GotoMark方法用于快速地將記錄指針定位到具有書簽的記錄處。FreeBookmark方法是與GetBookMark方法相反的操作,它釋放書簽標(biāo)志。下面的程序代碼闡述了書簽操作的一般方法:Book

27、Mark : TBookMark;<Do something>BookMark := Table1.GetBookMark; 對當(dāng)前記錄作書簽標(biāo)志Table1.DisalbeControls; 切斷Table1與數(shù)據(jù)察覺部件的聯(lián)系While Not EOF Do 對表中全部記錄進行其他處理begin<Do something>Tabel1.Next;end;Tabel1.GotoBookMark(BookMark)Table1.enableControls; 重新定位記錄指針回到原來的位置Tabel1.FreeBookMark(BookMark); 刪除書簽BookMa

28、rk標(biāo)志15.3.5 數(shù)據(jù)集部件與數(shù)據(jù)瀏覽部件的連接數(shù)據(jù)集部件TTabel和TQuery具有三個方法,DisableControls 方法、EnableControls方法、Refresh方法用于控制數(shù)據(jù)集部件和與其相連的數(shù)據(jù)瀏覽部件之間的連接,以及控制數(shù)據(jù)瀏覽部件的顯示。在用戶修改和更新以及遍歷數(shù)據(jù)庫表中的記錄時,調(diào)用DisableControls方法具有重要意義,調(diào)用DisbaleControls方法以切斷TTable或TQuery部件與數(shù)據(jù)瀏覽部件的連接,使數(shù)據(jù)瀏覽部件暫時失效,否則,在對TTable或TQuery部件的每次修改之后,窗體中所有與它們相連的數(shù)據(jù)瀏覽部件都要更新其顯示內(nèi)容,

29、這親顯然會減慢處理速度。當(dāng)遍歷表中的記錄時記錄指針每移動一下,窗體中的數(shù)據(jù)瀏覽部件也隨之更新一下其中的顯示內(nèi)容,在屏幕上產(chǎn)生閃爍。EnableControls方法的作用與DisbaleControls方法的作用是相反的,調(diào)用EnableControls方法,使TTable或TQuery部件恢復(fù)與數(shù)據(jù)瀏覽部件的連接,使暫時失效的數(shù)據(jù)瀏覽部件恢復(fù)到正常顯示表中記錄信息的狀態(tài)。Refresh方法用于刷新數(shù)據(jù)瀏覽部件中的顯示。在調(diào)用Refresh方法時,必須要確保TTable或TQuery部件是打開的。當(dāng)數(shù)據(jù)集中的記錄被修改之后,調(diào)用Refresh方法,數(shù)據(jù)瀏覽部件中顯示的信息也隨之改變。15.3.6

30、 數(shù)據(jù)集部件的事件數(shù)據(jù)集部件TTable或TQuery具有很多的事件。為這些事件編寫相應(yīng)的程序代碼可以進行有效性驗證、計算可計算字段的值、確認(rèn)對數(shù)據(jù)庫表的多種操作等等。這些事件及其描述如表15.4所示。表15.4 數(shù)據(jù)集部件常用的事件 事 件 描 述 BeforeOpen,Afteropen 在數(shù)據(jù)集部件被打開之前/之后被觸發(fā) BeforeClose,Afterclose 在數(shù)據(jù)集部件被關(guān)閉之前/之后被觸發(fā) BeforeInsert,AfterInsert 在數(shù)據(jù)集部件進入插入狀態(tài)之前/之后被觸發(fā) BeforeEdit,AfterEdit 在數(shù)據(jù)集部件被編輯之前/之后被觸發(fā) BeforePos

31、t,AfterPost 在數(shù)據(jù)集部件投寄被修改的記錄之前/之后被觸發(fā)BeforeCancel,AfterCancel 在數(shù)據(jù)集部件取消前一步操作之前/之后被觸發(fā) BeforeDelete,AfterDelete 在數(shù)據(jù)集部件刪除當(dāng)前記錄之前/之后被觸發(fā) OnNewRecord 當(dāng)建立一條新記錄時被觸發(fā) OnCalcFields 當(dāng)為表中的計算字段計算字段值時被觸發(fā)15.4 TTable部件及應(yīng)用在前一節(jié)里我們介紹了數(shù)據(jù)集部件TTable 和TQuery 的共同的一些屬性和方法。TTable部件是Delphi數(shù)據(jù)庫編程中要經(jīng)常使用的最重要的部件之一,它是數(shù)據(jù)庫應(yīng)用程序訪問數(shù)據(jù)庫時必須使用的數(shù)據(jù)集

32、部件之一,在這一節(jié)里,我們重點介紹TTable部件特有的屬性和方法,TTable部件所有的屬性、方法和事件都可以在聯(lián)機幫助中查到。15.4.1 TTabel部件主要的屬性DatabaseName屬性和TableName屬性:DatabaseName屬性是說明數(shù)據(jù)庫應(yīng)用程序所操作的數(shù)據(jù)庫的名字,它可以是由BDE定義的數(shù)據(jù)庫的別名、顯式說明的數(shù)據(jù)庫文件所在的磁盤路徑或者由TDatabase部件定義的一個數(shù)據(jù)庫名。DatabaseName屬性常常是一個由BDE定義的數(shù)據(jù)庫的別名。使用由BDE定義的數(shù)據(jù)庫的別名代替數(shù)據(jù)庫實際所在的路徑和名字,好處是當(dāng)實際的數(shù)據(jù)庫存放的位置發(fā)生變化時,只需利用BDE簡單

33、地設(shè)置一下該數(shù)據(jù)庫的別名,而數(shù)據(jù)庫應(yīng)用程序無需修改。有關(guān)BDE的使用請參看BDE的設(shè)置應(yīng)用。TabelName屬性用以說明當(dāng)前TTable部件所連接的實際的數(shù)據(jù)庫表。這兩個屬性一般都在設(shè)計階段指定,當(dāng)然在程序運行過程中也可以設(shè)置,但是要修改這兩個屬性時,必須要在TTabel的Active屬性為False時進行,當(dāng)TTable的Active屬性為True時,這兩個屬性是不能被修改和設(shè)置的。TableType屬性:該屬性說明與TTable部件相連接的數(shù)據(jù)庫表的類型。當(dāng)TableType屬性設(shè)置成Default時,該屬性所說明的數(shù)據(jù)庫表的類型由數(shù)據(jù)庫文件的擴展名決定。 若數(shù)據(jù)庫文件的擴展名為.DB或

34、沒有擴展名,表的類型是Paradox表 若數(shù)據(jù)庫文件的擴展名為.DBF時,表的類型是dBASE表 若數(shù)據(jù)庫文件的擴展名為.TXT時,表的類型是ASCII表如果TableType屬性不設(shè)定為Default,那么與TTable 部件相連的數(shù)據(jù)庫表的類型由TableType中的設(shè)置的值決定,不用考慮數(shù)據(jù)庫文件的擴展名。KeyExclusive屬性:該屬性的一個作用是說明在數(shù)據(jù)庫表中查找記錄時,將記錄移到與查找值相匹配的記錄處還是將記錄指針移到與查找值相匹配的記錄后面一條記錄處。該屬性是布爾型變量,當(dāng)它的值為False時(缺省情況下為False),將記錄指針移到相匹配的記錄處,為True時,將記錄指針

35、移到相匹配記錄的后面一條記錄處。該屬性另一個作用是在表中指定檢索范圍時,用來說明是否包括滿足過濾條件的邊界記錄。當(dāng)KeyExclusive的值為False時,檢索范圍包括邊界記錄,否則不包括邊界記錄,有關(guān)詳細(xì)的操作請參看“限定表中記錄的檢索范圍”。 IndexFields屬性和IndexFieldsCount屬性:IndexFields的屬性值是數(shù)據(jù)庫表中字段名列表,它包含與TTable部件相連的數(shù)據(jù)庫表中的全部索引字希。IndexFieldsCount屬性說明表中索引字段的個數(shù)。這兩個屬性值都是只讀的,只有在程序運行過程中可用。IndexName屬性和IndexFieldNames屬性:In

36、dexName屬性中存放著在建立數(shù)據(jù)庫表時為數(shù)據(jù)庫表定義的所有輔助索引名,它是一個輔助索引名列表,是只讀屬性。IndexFieldNames屬性指定用于數(shù)據(jù)庫表索引排序的字段名,多個字段名之間用分號隔開。例如對Customer.DB表中的客戶記錄按郵政編碼ZipCode和客戶號碼CustNo排序時可以設(shè)定IndexFieldNames的值為:ZipCode ; CustNo在IndexFieldNames屬性中指定的字段必須存在于相應(yīng)的數(shù)據(jù)庫表中,否則會導(dǎo)致錯誤。IndexName和IndexFieldName是互斥的,每次只能指定其中一個屬性的值,不能同時為兩個屬性都指定屬性值。Exclus

37、ive屬性:該屬性是一個布爾型屬性,它標(biāo)明是否以共享方式打開數(shù)據(jù)庫表,如果Exclusive的值為True,當(dāng)打開一個數(shù)據(jù)庫表時,其他用戶就不能訪問該表了,若Exclusive的值為False,將以共享方式打開一個數(shù)據(jù)庫表。顯然不能將其他用戶正在訪問的表以互斥方式打開(設(shè)定Exclusive的值為True)。對于SQL數(shù)據(jù)庫服務(wù)器上的數(shù)據(jù)庫表,當(dāng)以互斥方式被一個用戶打開時,其他用戶可以讀取該表中的數(shù)據(jù),但不能修改表中的數(shù)據(jù),當(dāng)然有些數(shù)據(jù)庫服務(wù)器不支持這種方式,這要具體參看有關(guān)的數(shù)據(jù)庫服務(wù)器的文檔。ReadOnly屬性和CanModify屬性:這兩個屬性都是布爾型屬性,ReadOnly屬性決定用

38、戶是否能夠?qū)Ρ碇械臄?shù)據(jù)進行讀寫。ReadOnly為True 時,用戶只能讀取表中的數(shù)據(jù),ReadOnly為False時,用戶可以讀寫表中的數(shù)據(jù)(假設(shè)數(shù)據(jù)庫已授權(quán)用戶能夠讀寫其中的數(shù)據(jù)庫表)。CanModify屬性是一個只讀屬性,用戶不能夠修改其屬性值,它反映了用戶對數(shù)據(jù)庫表擁有的實際特權(quán),當(dāng)ReadOnly為True時CanModify將自動地被置為False,當(dāng)ReadOnly為False時,如果數(shù)據(jù)庫允許用戶對表進行讀寫時,CanModify為True,否則CanModify為False。當(dāng)CanModify為False時,數(shù)據(jù)庫表是只讀的,但不能將其置成編輯狀態(tài)或插入狀態(tài);當(dāng)CanMod

39、ify屬性為True時,雖然數(shù)據(jù)庫表對應(yīng)的數(shù)據(jù)集部件可以置成編輯和插入狀態(tài),但是這并不意味著用戶能夠插入和修改表中的數(shù)據(jù),因為這還要受到其他因素的限制,如用戶對SQL數(shù)據(jù)庫服務(wù)器的訪問權(quán)限等的限制。TTable部件還有其他一些屬性請參看聯(lián)機幫助15.4.2 TTable部件的方法及應(yīng)用15.4.2.1 設(shè)定數(shù)據(jù)庫表的使用范圍在我們實際應(yīng)用中的數(shù)據(jù)庫表中常常存放著大量的數(shù)據(jù)信息,其中包含著很多的記錄,而我們的應(yīng)用程序可能只需對其中一部分記錄進行操作,因此,為應(yīng)用程序指定一個使用范圍就顯得特別重要了,為方便有效地指定數(shù)據(jù)庫表的使用范圍Delphi為TTable部件提供了下列方法供用戶使用: Set

40、RangeStart和EditRangeStart方法 SetRangeEnd和EditRangeEnd方法 SetRange(Start Values,End Values)方法 ApplyRange方法 CancelRange方法1. SetRangeStart方法用于指定檢索范圍的起始記錄,調(diào)用SetRangeStart方法之后,可以為起始記錄的一個或多個字段指定相應(yīng)的字段值。SetRangeEnd方法用于指定檢索范圍的結(jié)束記錄,調(diào)用SetRangeEnd方法之后,可以為結(jié)束記錄的一個或多個字段指定相應(yīng)的字段值。2. SetRange方法SetRange方法包含了SetRangeStar

41、t和SetRangeEnd方法的功能,它可以同時指定檢索范圍的起始和結(jié)束記錄,起始記錄和結(jié)束記錄的字段值以數(shù)組形式送給SetRange,其基本形式是:SetRange(起始值,結(jié)束值)3. ApplyRange方法根據(jù)SetRangeStart,SetRangeEnd或SetRange方法說明的檢索范圍的起始和結(jié)束記錄,具體設(shè)定一個檢索范圍,調(diào)用ApplyRange方法之后,應(yīng)用程序只能對檢索范圍內(nèi)的記錄進行有關(guān)的操作。4. CancelRange方法 CancelRange方法的作用與ApplyRange方法的作用是相反的,這是取消為表設(shè)定的檢索范圍,調(diào)用CancelRange方法之后應(yīng)用程

42、序可以對表中全部記錄進行有關(guān)的操作。在這里要注意的是:如果我們使用的是paradox表或dBASE表,在調(diào)用SetRangeStart,SetRangeEnd以及SetRange方法時,只能為表中的索引字段或定義的索引指定相應(yīng)的字段值,以設(shè)定檢索范圍。如果使用SQL數(shù)據(jù)庫服務(wù)器中的數(shù)據(jù)庫表,可以為IndexFieldNames屬性中指定的字段指定相應(yīng)的字段值。例如:假設(shè)Table1與Customer.DB表相連,Customer.DB中一個索引字段是CustNo,同時應(yīng)用窗體中有兩個編輯框StartVal和EndVal用于輸入起始、結(jié)束記錄的字段CustNo的值,下面的程序代碼便可以為我們設(shè)定

43、一個檢索范圍:Tabel1.SetRangeStart; 指定檢索范圍的起始記錄Tabel1CustNo.AsString:= StartVal.Text 為起始記錄的CustNo字段指定字段值 Tabel1.SetRangeEnd; 指定檢索范圍的結(jié)束記錄if EndVal.Text <> ' ' thenTabel1CustNo.AsString := EndVal.Text; 為結(jié)束記錄的CustNo 字段指定字段值 Tabel1.ApplyRange; 根據(jù)檢索范圍的起始、結(jié)束記錄設(shè)定檢索范圍注意上面的程序代碼,在為結(jié)束記錄的CustNo字段指定字段值時,首

44、先檢查EndVal的值是否為空,如果EndVal的值為空,那么設(shè)定的檢索范圍沒有包含一條記錄,因為沒有任何記錄的字段值小于NIL;如果StartVal的值為空,那么檢索范圍將從表中的第一條記錄開始,因為表中任何記錄的字段值都大于空(NIL)。上述代碼可以用SetRange方法改寫成:If EndVal.Text <>' ' thenTabel1.SetRane(StartVal.Text.EndVal.Text);Table1.ApplyRange;EditRangeStart和EditRangeEnd方法的使用完全類似于SetRangeStart和SetRange

45、End方法,只是調(diào)這兩個方法是設(shè)定一個可編輯的范圍。又如:假設(shè)一個表中的一個索引包含兩個字段LastName和FirstName,我們?yōu)樗饕械囊粋€字段或多個字段指定相應(yīng)的字段值,設(shè)定數(shù)據(jù)庫表的使用范圍。Table1.SetRangeStart;Table1.FieldByName('LastName').Asstring := 'Smith'Table1.SetRangeEnd;Tabel1.ApplyRange;上述代碼設(shè)定的范圍包括LastName字段的值大于或等于Smith的所有記錄。而下面的代碼設(shè)定的范圍則包括LastName字段的值大于或等于Smit

46、h且FirstName字段的值大于或等于'J'的記錄。Table1.SetRangeStart;Table1.FieldByName('LastName').Asstring := 'Smith'Table1.FieldByName('FirstName').Asstring := 'J'Table1.SetRangeEnd;Tabel1.ApplyRange;15.4.2.2 查找數(shù)據(jù)庫表中的記錄如果想查找數(shù)據(jù)庫表中的記錄,必須想指定查找記錄的一些字段的字段值,然后在表中進行檢索,檢索出與查找值相匹配的記錄來。如

47、果我們是在Paradox或dBASE數(shù)據(jù)庫中的表中查找記錄,那么查找值所對應(yīng)的字段必須是表中的關(guān)鍵字段或輔助索引字段。如果查找SQL數(shù)據(jù)庫服務(wù)器中的表,那么查找值必須是表的IndexFieldNames屬性中指定的字段。Delphi提供了兩種方式在數(shù)據(jù)庫表中查找記錄:Goto方式和Find方式。這兩種方式十分相似,它們的主要區(qū)別在于為查找指定查找值的方法不一樣。使用Goto方式進行數(shù)據(jù)查找使用的方法有SetKey方法、GotoKey方法和GotoNearest方法。其實際步驟如下:確保要查找的字段是關(guān)鍵字段或輔助索引字段。調(diào)用SetKey方法把與表對應(yīng)的TTable部件置成查找狀態(tài)。把查找值賦

48、給相應(yīng)的字段。調(diào)用GotoKey方法,并測試它的返回值檢驗查找是否成功。假設(shè)Table1對應(yīng)的表中第一個字段是關(guān)鍵字段,Edit1是應(yīng)用窗體中的一個編輯框,用戶可以通過Edit1輸入查找值。下面的代碼將通過Goto方式進行查找。Table1.SetKey; 將Table1置成查找狀態(tài)Table1.Field0.AsString := Edit1.Text; 指定查找值Table1.GotoKey; 進行查找上面最后一行代碼是根據(jù)用戶指定的查找值,在表中執(zhí)行查找。查找的結(jié)果有兩種,也許成功也許失敗,這是由調(diào)用GotoKey方法之后返回的布爾值來決定,如果返回True,那么查找成功,并且記錄指針會

49、指向與查找值匹配的記錄,如果返回Fale,那么查找失敗,記錄指針的位置不發(fā)生變化。下面的代碼可以測試調(diào)用GotoKey方法之后的返回值,告知用戶查找是否成功。Table1.SetKey;Table1.Field0.AsString:= 'Smith'If not Table1.GotoKey thenShowMessage('記錄沒找到')在這一段代碼中,如果在表中沒有找到第一個字段值為Smith的記錄,該應(yīng)用程序會彈出一個對話框告知用戶“記錄沒有找到”。如果在表中存在多個關(guān)鍵字段或輔助索引中包含多個字段時,你在進行查找時,只想為第一個字段指定查找值,那么必須要

50、設(shè)置TTable部件的KeyFieldCount的屬性值為1。如果想為多個字段指定查找值,只能為相鄰的字段指定查找值,例如輔助索引中共有三個字段,那么我們只能為第一個字段、第一和第二個字段、第一和第二以及第三個字段指定查找值,而不能為第一和第三個字段指定查找值。GotoNearest方法的使用與GotoKey方法完全一樣,只是它用于不精確查找,它不要求查找結(jié)果與查找值精確匹配,當(dāng)表中有與查找值精確匹配的記錄時,它將記錄指針移到該記錄處,當(dāng)表中沒有與查找值精確匹配的記錄時,它會查找出與查找值最接近的記錄,并將記錄指針移到該記錄處。下面是應(yīng)用GotoNearest方法的一段代碼:Table1.Se

51、tKey;Table1.Fields0.AsString:= 'Sm'Table1.GotoNearest;執(zhí)行上述代碼后,若表中存在第一個字段值等于Sm的記錄時,記錄指針將移到該記錄處,若表中不存在第一個字段值等于Sm的記錄,而存在第一個字段值等于Smith的記錄,那么記錄指針會移到該記錄處。如果我們不是以數(shù)據(jù)庫表中的關(guān)鍵字段作為查找字段,我們也可以為TTable部件的IndexFieldName屬性中的字段或IndexName屬性中的字段指定查找值進行數(shù)據(jù)查找。例如,假設(shè)Customer表中有一個名叫CityIndex的輔助索引,我們?yōu)镃ityIndex中的字段指定查找值進

52、行查找時,首先設(shè)置TTable部件的IndexName屬性為CityIndex,然后再進行查找,下面是具體的程序代碼:Table1.IndexName := 'CityIndex'Table1.Open;Table1.SetKey;Table1.FieldByName'City').AsString := Edit1.Text;Table1.GotoKey;使用Find方式:使用Find方式在數(shù)據(jù)庫中進行數(shù)據(jù)查找的方法有:FindNearest方法和FindKey方法。FindKey方法和FindNearest方法為數(shù)據(jù)查找提供了一個簡單的方法,它們將SetKe

53、y、指定查找值、執(zhí)行查找三個步驟融合在一步里完成,它們在指定查找值時,是把各字段的查找值組成一個數(shù)組傳給FindKey或FindNearest。下面是使FindKey方法的一個例子。 假設(shè)Tabel1對應(yīng)的表中的第一個字段是關(guān)鍵字段。Table.FindKey(Edit1.Text);如果用GotoKey方法完成這一功能則需要編寫下面代碼:Table1.SetKey;Table1.Fields0.AsStrine := Edit.Text;Table1.GotoKey;FindKey方法和FindNearest方法的區(qū)別與GotoKey和GotoNearest方法的區(qū)別是一樣的。15.4.2.

54、3 創(chuàng)建主要明細(xì)數(shù)據(jù)庫應(yīng)用TTable部件中MasterSource屬性和MasterFields屬性是用于定義兩個數(shù)據(jù)庫表的一對多的關(guān)系。MasterSource屬性指定主表對應(yīng)的TDataSource部件,MasterFields屬性指定主表和明細(xì)表之間建立聯(lián)系的字段,主表和明細(xì)表之間建立一對多關(guān)系時,可能不只是基于一個字段,可能有多個字段。如果有多個字段,那么在說明MasterFields屬性時,多個字段之間要用分號隔開。如Table1.MasterFields := 'OrderNo;CustNo'。在設(shè)計階段可以使用字段連接設(shè)計器(Field Link Designe

55、r)為兩上表創(chuàng)建一對多的關(guān)系,在Object Inspector 中雙擊TTable部件的MasterFields便可以打開Field Link Designer,進行一對多關(guān)系的創(chuàng)建。 如創(chuàng)建Customer.DB表和Order.DB表之間的一對多關(guān)系時,使用Field Link Designer 如圖15.5所示。圖15.5 使用Field Link Designer創(chuàng)建一對多關(guān)系Field Link Designer提供了一種可視化的方法來創(chuàng)建主要明細(xì)表之間的一對多關(guān)系。圖中Available Indexes組合框中存放著明細(xì)表中的關(guān)鍵字段和索引字段,可以選擇索引字段進行連接。在主表中選

56、擇一個用于連接的關(guān)鍵字段,然后將其與明細(xì)表中相應(yīng)的關(guān)鍵字段連接,單擊Add按鈕,主要明細(xì)表的連接字段將顯示在Joined Fields列表框中,如: CustNo->CustNo15.5 TDataSource部件及其應(yīng)用TDataSource部件是開發(fā)數(shù)據(jù)庫應(yīng)用程序中用到的非常重要的部件,它是連接數(shù)據(jù)集部件TTable或TQuery和數(shù)據(jù)瀏覽部件的橋梁。TDataSource部件本身十分簡單,它所擁有的屬性、事件和方法都比較少,在使用該部件時無需作太多的工作,它主要是為數(shù)據(jù)瀏覽部件服務(wù)的,如果在應(yīng)用程序中沒有使用數(shù)據(jù)瀏覽部件,我們也沒有必要為應(yīng)用程序設(shè)置TDataSource部件。15.5.1 TDataSource部件的屬性TDataSource部件除了其他部件都擁有的Name屬性和Tag屬性之外,主要有下面幾個屬性: DataSet屬性:該屬性說明TDataSource部件從中獲取數(shù)據(jù)的數(shù)據(jù)

溫馨提示

  • 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
  • 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
  • 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
  • 5. 人人文庫網(wǎng)僅提供信息存儲空間,僅對用戶上傳內(nèi)容的表現(xiàn)方式做保護處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負(fù)責(zé)。
  • 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請與我們聯(lián)系,我們立即糾正。
  • 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時也不承擔(dān)用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。

評論

0/150

提交評論