桌面數(shù)據(jù)庫開發(fā)_第1頁
桌面數(shù)據(jù)庫開發(fā)_第2頁
桌面數(shù)據(jù)庫開發(fā)_第3頁
桌面數(shù)據(jù)庫開發(fā)_第4頁
已閱讀5頁,還剩26頁未讀, 繼續(xù)免費(fèi)閱讀

下載本文檔

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

文檔簡介

1、.1.編寫桌面數(shù)據(jù)庫應(yīng)用1.1.使用數(shù)據(jù)集數(shù)據(jù)集是以行和列的形式組織起來的數(shù)據(jù)的集合。其中,每一列具有相同的數(shù)據(jù)類型,而每行是由各列指定類型的數(shù)據(jù)組成的。 數(shù)據(jù)集的每一列被稱為一個字段,每一行被稱為一個記錄。 V C L把數(shù)據(jù)集封裝在一個稱為 TDataSet的抽象組件中。在 TataSet 中引入了許多用于操作和瀏覽數(shù)據(jù)集的屬性和方法。1.1.1 VCL 的數(shù)據(jù)庫體系結(jié)構(gòu)在開發(fā) Delphi 3期間, V C L的數(shù)據(jù)庫體系結(jié)構(gòu)已經(jīng)有了令人注目的修改,為了在 D e l p h i 程序中能方便地訪問一些非 B D E的數(shù)據(jù)集,它開放了數(shù)據(jù)集體系結(jié)構(gòu)。 T D a t a S e t 類位于

2、整個體系結(jié)構(gòu)的頂層。 T D a t a S e t 是一個用來抽象地表示數(shù)據(jù)集的記錄和字段的組件。 為了實(shí)現(xiàn)對一些特殊的物理數(shù)據(jù)格式的訪問,你可以在程序中覆蓋 T D d a t a S e t類的方法。1.1.2 BDE 數(shù)據(jù)訪問組件在組件面板的 Data Access 頁上可以找到用于訪問和管理B D E數(shù)據(jù)集的 V C L組件,如圖 2 8 - 1 所示。 V C L用三種組件來表達(dá)數(shù)據(jù)集:T Ta b l e、T Q u e ry和T S t o r e d P r o c。T Ta b l e是表達(dá)數(shù)據(jù)庫表中的數(shù)據(jù)和結(jié)構(gòu)的組件;TQ u e r y 是利用 S Q L對數(shù)據(jù)進(jìn)行查詢

3、并返回?cái)?shù)據(jù)集的組件。 T S t o r e P r o c 是封裝了 S Q L 服務(wù)器上的一個存儲過程的組件。本章中,我們將使用 T Ta b l e 組件討論數(shù)據(jù)集。稍后再介紹 T Q u e r y 組件。1.1.3 打開一個數(shù)據(jù)集如果是訪問 S Q L服務(wù)器,那么在 打開數(shù)據(jù)庫中的一個數(shù)據(jù)集之前,一定要先建立數(shù)據(jù)庫連接。當(dāng)你關(guān)閉掉數(shù)據(jù)庫中最后一個數(shù)據(jù)集時,連接就會終止。 建立和斷開數(shù)據(jù)庫的連接都會有一些開銷。如果你經(jīng)常執(zhí)行開關(guān)數(shù)據(jù)庫的操作,那么應(yīng)該利用 T D a t a b a s e 組件來管理對 S Q L 服務(wù)器的連接。.在對數(shù)據(jù)集進(jìn)行操作之前,必須先將它打開。我們用O p

4、e n ( )方法來實(shí)現(xiàn)。請看示例:Table1.Open();你也可以通過將數(shù)據(jù)集的A c t i v e屬性設(shè)為 Tr u e 來打開它:Table1.Active:=True;使用第二種方法的開銷更小一些,因?yàn)槔肙 p e n ( )方法來實(shí)現(xiàn)最終還是要將數(shù)據(jù)集的 A c t i v e屬性設(shè)為 Tr u e 。不過,這點(diǎn)小開銷可以忽略。當(dāng)數(shù)據(jù)集被打開后,我們就可以自由地操作和使用它了。在一系列的操作完成后,不要忘記要調(diào)用 C l o s e ( )方法將它關(guān)閉。如下:Table1.Close();當(dāng)然,你也可以通過把 A c t i v e屬性設(shè)為 F a l s e來關(guān)閉數(shù)據(jù)集。例

5、如:Table1.Active:=False;1.1.4 瀏覽數(shù)據(jù)集T D a t a S e t 提供了簡單的方法來瀏覽數(shù)據(jù)集中的記錄。 First() 將當(dāng)前的記錄指針定位在數(shù)據(jù)集中的第一個記錄; L a s t ( ) 把當(dāng)前的記錄指針定位在數(shù)據(jù)集中的最后一個記錄;N e x t ( )和P r i o r ( )分別使當(dāng)前記錄指針向前或向后移動一個記錄。另外,M o v e B y ( )方法用于向前或向后移動一定數(shù)量的記錄。1.1.4.1. BOF 、E O F 和循環(huán)B O F和E O F都是 T D a t a S e t 中布爾類型的屬性,分別表示當(dāng)前記錄是否是第一個記錄和最后

6、一個記錄。例如,如果需要遍歷數(shù)據(jù)集中的每一條記錄,最容易實(shí)現(xiàn)的方法就是利用一個 w h i l e循環(huán)來使指針從第一個記錄不斷地向后移動直到E O F為真Table1.First;While not Table1.Eof do begin Do something; Table1.Next;End;1.1.4.2.書簽書簽?zāi)茉跀?shù)據(jù)集中保存當(dāng)前的位置,以便以后可以回到那個位置。在 D e l p h i 中書簽的使用非常簡單,你只需要使用一個屬性。 Delphi 用 T B o o k m a r k S t r 類型來表示書簽, T Ta b l e 的Bookmark 屬性便是此種類型。當(dāng)從

7、 B o o k m a.r k中讀值時,你就獲取了一個書簽;當(dāng)你寫到它時,就可以定位在書簽所指示的記錄位置。當(dāng)你對數(shù)據(jù)集的某個地方感興趣并且想能標(biāo)記以便日后訪問時,Var BM:TBookMarkStr;/ 聲明BeginBM:=Table1.BookMark;/定義Table1.BookMark:=BM;/回到這個書簽標(biāo)記的位置BM:= ;End1.1.4.3. TDataSource我們在前面的程序中用到了T D a t a S o u r c e組件,所以我們將在這里詳細(xì)討論這個組件。 T D a t a S o u r c e是一個數(shù)據(jù)庫連接中介,它使數(shù)據(jù)訪問組件 ( 如 T Ta

8、b l e ) 能向數(shù)據(jù)感知組件提供數(shù)據(jù)。它不但在數(shù)據(jù)訪問和數(shù)據(jù)感知兩方面起到了接口的作用, 而且,它還包含了一些使數(shù)據(jù)操作變得更簡單的屬性和事件。T D a t a S o u r c e 的S t a t e 屬性表示當(dāng)前連接的底層數(shù)據(jù)集的狀態(tài)。它可以表明數(shù)據(jù)集是處于未活動的狀態(tài)還是插入、編輯、設(shè)置鍵值或是計(jì)算字段狀態(tài)。S t a t e屬性的值的變化會導(dǎo)致發(fā)出O n S t a t e C h a n g e事件。 TD a t a S e t的O n D a t a C h a n g e事件是在數(shù)據(jù)集變成活動狀態(tài)或數(shù)據(jù)感知組件通知數(shù)據(jù)集數(shù)據(jù)發(fā)生改變時被觸發(fā)。On U p d a t

9、e D a t a 事件在記錄被提交或更新時被觸發(fā),在處理此事件時,一般會改變數(shù)據(jù)感知組件顯示的數(shù)據(jù),這種改變依賴于數(shù)據(jù)庫表的內(nèi)容。響應(yīng)此事件你可以使跟蹤程序中類似的改變。1.1.5 對字段操作1.1.5.1.字段值訪問字段的值需要用到 T D a t a s e t的數(shù)組屬性 F i e l d s 或F i e ld s B y N a m e ( )函數(shù)。F i e l d s 0 將返回一個 T F i e l d對象,它表示數(shù)據(jù)集的第一個邏輯字段。S:=Table1.Fields0.AsStringF i e l d s B y N a m e ( ) 函數(shù)需要輸入字段名作為參數(shù),并

10、返回一個字段對象。.S:= Table1.FieldsByName( Name ).AsString;1.1.5.2.字段數(shù)據(jù)類型T F i e l d的D a t a Ty p e屬性可以告訴你字段的類型,所返回的字段類型只與數(shù)據(jù)庫類型有關(guān),與O b j e c tP a s c a l的數(shù)據(jù)類型無關(guān)。1.1.5.3 字段名和編號利用 T F i e l d的F i e l d N a m e屬性能得到某個字段的字段名。S:=Table1.Fields0.FieldName;利用 F i e l d N o屬性可以獲取某個字段對應(yīng)的編號。S:= Table1.FieldsByName( Na

11、me ).FieldNo;1.1.5.4.操作字段數(shù)據(jù)編輯Table1.Edit;Table1.FieldByName( Name).AsString:=LTMa;Table1.Post;Table1.Cancle;/也可以用 Cancle 來取消操作插入Table1.Insert;/或者 Table1.AppendTable1.FieldByName( Name).AsString:=LTMa;Table1.Post;Table1.Cancle;/也可以用 Cancle 來取消操作刪除Table1.Last;Table1.Delete;數(shù)據(jù)集在插入、添加或編輯狀態(tài)時,記住,只要離開當(dāng)前記錄,

12、對數(shù)據(jù)的改變就會被提交給數(shù)據(jù)庫。 因此,在編輯數(shù)據(jù)時要小心使用N e x t ( ) 、P r i o r ( ) 、F i r s t ( )、 L a s t ( )或M o v e B y ( )等方法。我們可以利用C a n c e l( ) 方法來取消當(dāng)前對數(shù)據(jù)集的修改。C a n c e l ( )方法不但取消了對數(shù)據(jù)的修改,也同時取消了當(dāng)前數(shù)據(jù)集的模式狀態(tài),回到了瀏覽模式.1.1.6 刷新數(shù)據(jù)集編寫數(shù)據(jù)庫程序時,一定要清楚地認(rèn)識到,數(shù)據(jù)集中的數(shù)據(jù)是一直在變化的。這就是說,數(shù)據(jù)集中的數(shù)據(jù)將會不斷地被添加、 刪除或修改, 尤其是對于網(wǎng)絡(luò)環(huán)境。因此,你必須不停地從磁盤或內(nèi)存中重新讀取數(shù)

13、據(jù)集中的信息來更新當(dāng)前所使用的數(shù)據(jù)集。更新數(shù)據(jù)集,可以使用 TDataset的R e f r e s h ( )方法。對 R e f r es h ( ) 的調(diào)用相當(dāng)于先調(diào)用 C l o s e ( )方法,再調(diào)用 O p e n ( ) 方法,但是調(diào)用 R e f r e s h ( )方法要快一些。 R e f r e s h ( )方法適用于所有的本地表;而對于來自 S Q L 數(shù)據(jù)庫服務(wù)器的數(shù)據(jù)庫, R e f r e s h ( )方法使用起來有些限制。在B D E試圖進(jìn)行 R e f r e s h ( )操作之前,必須對 S Q L數(shù)據(jù)庫表和查詢定義一個唯一的索引。其原因是, R

14、 e f r e s h ( )的調(diào)用總是盡可能保持記錄當(dāng)前的狀態(tài)。所以, B D E 必須使用 S e e k ( )來定位到當(dāng)前的位置,而 S e e k ( )操作只對 S Q L 數(shù)據(jù)集適用,而且要求有一個唯一的索引。R e f r e s h ( )并不工作于連接到 S Q L 數(shù)據(jù)庫的 T Q u e r y組件。1.1.7 變化的狀態(tài)有時候,需要知道一個數(shù)據(jù)庫表當(dāng)前為編輯模式還是添加模式,或是否處于活動狀態(tài),這些信息都可以通過查看TDataset的S t a t e屬性來獲取。 S t a t e屬性的類型為 T D a t a S e t S t a t e,1.1.8 過濾器

15、如果利用過濾器, 只要使用 Object Pascal 代碼就能實(shí)現(xiàn)一些簡單的數(shù)據(jù)搜索或過濾。使用過濾器最主要的好處是不需要索引, 也不需要對數(shù)據(jù)集做任何其他的準(zhǔn)備工作。 當(dāng)然,過濾器和基于索引的查找比起來,速度還是稍微慢一些 ( 本章后面將會討論 ) ,但另一方面,它們對于任何類型的應(yīng)用程序都非常有用。1.1.8.1.過濾一個數(shù)據(jù)集D e l p h i 過濾機(jī)制的一個比較普遍的作用是只顯示數(shù)據(jù)集中的一些特定記錄。這是一個簡單的兩步操作:1) 創(chuàng)建一個處理數(shù)據(jù)集的 O n F i l t e r R e c o r d事件的過程。在這個.過程中,根據(jù)一個或多個字段的值來決定是否要包含某個記錄

16、。2) 將數(shù)據(jù)集的 F i l t e r d屬性設(shè)為 Tr u e 。1.1.8.2. FindFirst/FindNextT D a t a S e t還提供 F i n d F i r s t ( )、F i n d N e x t ( )、F i nd P r i o r ( )和F i n d L a s t ( )等方法。利用這些方法可以找出那些符合篩選條件的數(shù)據(jù)記錄。這些方法被O n F i l t e r R e c o r d事件處理過程調(diào)用,來對未經(jīng)過濾的數(shù)據(jù)集進(jìn)行操作。根據(jù)O n F i l t e r R e c o r d事件處理過程中給出的過濾條件,可以找出第一個、

17、下一個、前一個或最后一個匹配的記錄。每一個方法都不用輸入?yún)?shù),其返回值是一個表明是否找到匹配記錄的布爾值。1.1.8.3.定位一個記錄T D a t a S e t提供了一個名為 L o c a t e ( )的方法。由于 L o c a t e ( )使用過濾器進(jìn)行查找,所以與數(shù)據(jù)集中的任何索引都沒有關(guān)系1.2 使用 TTable 組件1.2.1 查找記錄當(dāng)需要查找數(shù)據(jù)庫表中的某些記錄時,可以使用V C L提供的若干方法。當(dāng)使用d B A S E 和P a r a d o x數(shù)據(jù)庫表時, Delphi會假定被查找的字段都已經(jīng)被定義了索引。對 S Q L數(shù)據(jù)庫表,如果所查找的字段沒有定義索引,

18、那么查詢的效率將會很低以致于無法忍受。例如,如果為一個數(shù)據(jù)庫表建立了兩個索引,第一個索引基于字段 1,它是數(shù)值類型的,第二個索引基于字段2,它是字母數(shù)字類型的。這樣就可以通過這兩個索引查找特定的記錄:即調(diào)用F i n d K e y ( )或者先調(diào)用 S e t Ke y ( )再調(diào)用 G o t o K e y ( )。1.2.1.1. FindKey()T Ta b l e組件的 F i n d K e y ( )方法可用來查找一個與關(guān)鍵字段匹配的記.錄。 F i n d K e y ( )需要傳遞一個 a r r a yof const類型的參數(shù)。如果調(diào)用成功,則返回 Tr u e 。例

19、如,在下面的代碼中,記錄指針被定位在這樣的記錄,其第一個字段取值為 1 2 3 、第二個字段中包含 h e l l o 字符串。If Not Table1.FindKey(123,Hello ) then MessageBeep(0);如果沒有找到匹配的記錄,F(xiàn) i n d K e y ( )將返回 F a l s e,并且計(jì)算機(jī)發(fā)出嘀的一聲。1.2.1.2. SetKey() 和 G o t o K e y ( )T Ta b l e的 S e t K e y ( )方法能夠使數(shù)據(jù)庫表進(jìn)入設(shè)置鍵值的模式。在指定了查找條件后就可以調(diào)用G o t o K e y ( )來從頭到尾地搜索一個記錄。

20、前面的例子如果改用 S e t K e y ( ) . . G o t o K e y ( )來寫,則為:1.2.1.3.最接近的匹配F i n d N e a r e s t ( )與前面類似,你也可以調(diào)用F i n d N e a r e s t ( )來查找數(shù)據(jù)庫表中與條件最接近匹配的記錄。例如要查找第一個字段與 1 2 3最接近的記錄,并返回第一個匹配的記錄,可以使用下面的代碼:Table1.FindNearest(123);同樣, F i n d N e a r e s t ( )也需要傳遞一組常量作為輸入?yún)?shù),這些常量參數(shù)包含的是被查找的記錄的字段值。當(dāng)查找成功時,如果K e y

21、E x c l u s iv e 屬性被設(shè)為 F a l s e,則記錄指針將指在第一個匹配的記錄上;如果K e y E xc l u s i v e屬性被設(shè)為 Tr u e ,則記錄指針指在匹配的后一個記錄。1.2.1.4.使用哪個索引以上的方法都假設(shè)你想基于數(shù)據(jù)庫表的主索引來進(jìn)行查找。如果使用副索引進(jìn)行查找,需要設(shè)置表對象的 I n d e x N a m e 屬性來指定一個索引。例如,如果數(shù)據(jù)庫表有一個基于 C o m p a n y 字段的副索引,名為 B y C o m p a n y ,下面的代碼查找 U n i s c o 公司:With Table1 do beginIndex

22、Name:= ByCompany ;FindKey( Unisco );End.注意在表打開的情況下,切換索引會有一些額外的開銷。如果在這時設(shè)置 I n d e x N a m e 屬性,可能會有一秒或更多的延遲。 對于 d B A S E 表和 P a r a d o x 表來說,只能基于定義了索引的字段進(jìn)行查找。對 S Q L數(shù)據(jù)庫來說,如果不是針對定義了索引的字段來設(shè)置范圍的話,性能將受到損害。1.2.1.5. SetRange()和 ApplyRange()與F i n d K e y ( )和F i n d N e a r e s t ( )類似, S e t R a n g e (

23、 )可以進(jìn)行復(fù)雜的操作。 S e t R a n g e ( )需要傳遞兩組 a r r a yof const類型的參數(shù),第一組參數(shù)表示字段取值范圍的下限, 第二組則表示字段取值范圍的上限。下面的代碼從數(shù)據(jù)庫中過濾出那些第一個字段取值大于等于 1 0 并且小于等于 1 5 的記錄:Table1.SetRange(10,15);要使用 A p p l y R a n g e ( )來設(shè)定取值范圍,可以按照下面的操作步驟:1) 調(diào)用 S e t R a n g e S t a r t ( )方法,并修改數(shù)據(jù)庫表的F i e l d s 數(shù)組屬性來設(shè)置關(guān)鍵字段的起始值。2) 調(diào)用 S e t R

24、a n g e E n d ( )方法,并再次修改 F i e l d s 數(shù)組屬性來設(shè)置關(guān)鍵字段的截止值。3) 調(diào)用 A p p l y R a n g e ( )建立新的取值范圍過濾器。對前面的例子,可以這樣改寫:提示應(yīng)該盡可能利用 S e t R a n g e ( )來過濾記錄,因?yàn)檫@樣會使代碼更簡潔,而且出錯的可能性會更小。如果想要從一個數(shù)據(jù)庫表中取消一個范圍過濾器,并且把數(shù)據(jù)庫恢復(fù)到調(diào)用ApplyRange ( )前的狀態(tài),可以調(diào)用 T Ta b l e組件的 C a n c e l R a n g e ( )方法,代碼如下:2.開發(fā) C/S 應(yīng)用程序摘自 DElPHI5 開發(fā)人員

25、指南第29 章.2.1 為什么要采用客戶/服務(wù)器結(jié)構(gòu)2.2 客戶 /服務(wù)器體系結(jié)構(gòu)2.3 客戶 /服務(wù)器模型2.4 客戶 /服務(wù)器與桌面數(shù)據(jù)庫開發(fā)的比較2.4.1 面向集合與面向記錄客戶程序并不是像桌面數(shù)據(jù)庫程序那樣直接面對數(shù)據(jù)庫表,而只是面對數(shù)據(jù)的子集??蛻舫绦蛟谙蚍?wù)器請求數(shù)據(jù)時,得到的數(shù)據(jù)可能是由一個或多個表中的字段構(gòu)成的,而請求是通過結(jié)構(gòu)化查詢語言 ( S Q L ) 實(shí)現(xiàn)的。通過 S Q L ,客戶端可以限制從服務(wù)器返回的記錄數(shù)??蛻舳送ㄟ^ S Q L語句從服務(wù)器上得到結(jié)果是服務(wù)器上的數(shù)據(jù)的一個子集。這一點(diǎn)很重要,因?yàn)閷τ谧烂鏀?shù)據(jù)庫應(yīng)用程序來說,它通過網(wǎng)絡(luò)所得到是整個數(shù)據(jù)庫表。 顯然

26、,數(shù)據(jù)庫表越大, 網(wǎng)絡(luò)的流量就越大。 客戶 / 服務(wù)器系統(tǒng)則不同,它只通過網(wǎng)絡(luò)傳送客戶請求的數(shù)據(jù),因而網(wǎng)絡(luò)流量較小,對網(wǎng)絡(luò)的要求也較低。這個區(qū)別也影響了對 S Q L數(shù)據(jù)集的瀏覽性。例如第一條、最后一條、下一條和上一條記錄等概念,對基于 S Q L的數(shù)據(jù)集來說不是固有的。尤其是當(dāng)查詢結(jié)果是由多個數(shù)據(jù)庫表組成的情況下更是如此。許多 S Q L服務(wù)器提供了可翻滾的指針,用于瀏覽 S Q L結(jié)果集。盡管如此,這與桌面數(shù)據(jù)庫的瀏覽還是不同的,因?yàn)楹笳咧苯俞槍?shù)據(jù)庫表進(jìn)行瀏覽。2.4.2 數(shù)據(jù)安全S Q L 數(shù)據(jù)庫處理數(shù)據(jù)安全的方式與桌面數(shù)據(jù)庫是不同的。 S Q L 數(shù)據(jù)庫不僅可以對數(shù)據(jù)庫進(jìn)行口令驗(yàn)證,

27、 而且還能夠針對特定的數(shù)據(jù)庫對象進(jìn)行限制, 包括視圖、數(shù)據(jù)庫表和存儲過程等。這意味著用戶訪問能夠在服務(wù)器端定義,來基于用戶的需要顯示數(shù)據(jù)。通常, S Q L數(shù)據(jù)庫允許通過 G R A N T或R E V O K E命令向一個用戶或一組用戶授予或收回權(quán)限。 因此,可以在 S Q L數(shù)據(jù)庫中定義一組用戶。這些權(quán)限可以應(yīng)用于任何一種已經(jīng)提到的數(shù)據(jù)庫對象。.2.4.3 記錄鎖定方法鎖定是一種機(jī)制,使得多個用戶可以對同一個數(shù)據(jù)庫提交并發(fā)的 S Q L事務(wù)。鎖定級別有多種,不同的服務(wù)器有不同的級別。表一級的鎖定主要用于限制對一個正在處理事務(wù)的數(shù)據(jù)庫表的訪問。盡管這種方式允許并行的處理,但這種鎖定機(jī)制速度很

28、慢,因?yàn)槎鄠€用戶往往要共享同一個表。頁面級鎖定是一種改進(jìn)的鎖定技術(shù)。用這種技術(shù),服務(wù)器可以把數(shù)據(jù)的某一塊鎖定在磁盤上,也就是所謂的頁面。當(dāng)一個事務(wù)正在對某頁進(jìn)行處理時,其他事務(wù)就不能更新該頁上的數(shù)據(jù)。由于數(shù)據(jù)往往分布在數(shù)百個頁面上,因此多個事務(wù)同時操作同一個頁面的可能性很小。有些服務(wù)器還提供了記錄級的鎖定機(jī)制, 能夠鎖定數(shù)據(jù)庫表中的某一行。 不過,這樣會大大增加鎖定信息的維護(hù)工作。桌面數(shù)據(jù)庫采用所謂的保守或明確的鎖定策略。這意味著,無法改變那些當(dāng)前正在被其他用戶更新的記錄。如果試圖訪問這樣的記錄,將會出錯,錯誤信息提示除非先前那個用戶釋放該記錄,否則無法訪問。S Q L數(shù)據(jù)庫采用所謂的優(yōu)化鎖定

29、策略。這種技術(shù)并不限制訪問當(dāng)前正在被其他用戶訪問的記錄, 可以照常對它進(jìn)行編輯, 并請求服務(wù)器保存修改后的數(shù)據(jù)。 不過,在記錄被保存之前,首先會與服務(wù)器中的備份進(jìn)行比較,因?yàn)樵诓榭春托薷倪@條記錄的同時,它可能已被其他用戶更新。如果該記錄已被其他用戶修改,則會導(dǎo)致一個錯誤,提示在取得記錄后,它已經(jīng)被更新。 作為一個開發(fā)人員,在設(shè)計(jì)客戶程序時應(yīng)該考慮到這一點(diǎn), 客戶 / 服務(wù)器程序尤其要注意到這種情況, 而在桌面數(shù)據(jù)庫中就不會發(fā)生。2.4.4 數(shù)據(jù)完整性對于 S Q L數(shù)據(jù)庫,可以對服務(wù)器中的數(shù)據(jù)進(jìn)行更健壯的完整性約束。盡管桌面數(shù)據(jù)庫也內(nèi)建了完整性驗(yàn)證的功能, 但需要在應(yīng)用程序的代碼中定義一些業(yè)務(wù)

30、規(guī)則。相對而言, S Q L 數(shù)據(jù)庫允許在服務(wù)器端定義這些規(guī)則 。這一點(diǎn)的好處是,不僅可以強(qiáng)制所有的客戶端程序都接受同一套規(guī)則的約束,而且可以集中維護(hù)這些規(guī)則。完整性約束是在服務(wù)器上創(chuàng)建數(shù)據(jù)庫表時定義的,完整性約束包括有效性、唯一性和參照性。完整性約束也可以在S Q L存儲過程中定義。 例如,在處理一個訂單之前,可以先檢查顧客的信用。2.4.5 面向事務(wù)S Q L數(shù)據(jù)庫是面向事務(wù)的。這意味著,對數(shù)據(jù)庫的修改不是像桌面數(shù)據(jù)庫那樣直接針對數(shù)據(jù)庫表進(jìn)行的,而是由客戶請求服務(wù)器進(jìn)行修改,服務(wù)器用一個事務(wù)來完成這一批操作。為了確保對數(shù)據(jù)庫的修改能夠有效,必須完整地提交事務(wù)。 如果事務(wù)中的任何一個操作失敗

31、,整個事務(wù)就會被回滾 ,換句話說,就是放棄。.事務(wù)能夠保證服務(wù)器上數(shù)據(jù)的一致性。還是以前面提到過的存貨系統(tǒng)為例,當(dāng)顧客提交了一份訂單后, O R D E R S表必須更新。另外, PA RT S表也必須相應(yīng)地把零件數(shù)減少。如果因?yàn)槟撤N原因,系統(tǒng)在更新 O R D E R S 表和 PA RT S表之間出錯, PART S表中的零件數(shù)就不能反映實(shí)際情況。但是,如果把整個操作放在一個事務(wù)中,除非整個事務(wù)正確地提交,否則,沒有一個表會有任何改變。在Delphi 5 中,對于事務(wù)既可以在服務(wù)器層進(jìn)行控制,也可以在客戶層進(jìn)行控制。2.5 SQL在客戶 /服務(wù)器開發(fā)中的角色2.6 Delphi客戶 /服務(wù)

32、器開發(fā)Delphi 5提供了一些數(shù)據(jù)庫對象組件,它們封裝了 B D E的功能。這樣,開發(fā)數(shù)據(jù)庫應(yīng)用程序就不必知道 B D E的功能。其次, Delphi 5 提供了數(shù)據(jù)感知組件可以與數(shù)據(jù)訪問組件彼此通信, 這樣,建立數(shù)據(jù)庫應(yīng)用程序的界面就變得簡單。 SQLLinks為連接 O r a c l e、S y b a s e、 I n f o r m i x、Microsoft SQL Server、 D B2和I n t e r B a s e提供了專門的驅(qū)動程序Delphi 5 還包含了 M I D A S 技術(shù),“ M I D A S:Multitier DistributedApplicat

33、ionServices Suite”。最后, D e l p h i 允許使用 CORBA(CommanObjectRequest Broker Architecture)來開發(fā)分布式應(yīng)用程序。C O R B A 規(guī)范已經(jīng)被OMG(Object Management Group)采用。通過 C O R B A技術(shù),可以創(chuàng)建面向?qū)ο蟮姆植际綉?yīng)用程序2.7 服務(wù)器:后端設(shè)計(jì)2.8 客戶:前端開發(fā)2.8.1 使用 TDatabase 組件T D a t a b s e組件可以更有效地控制數(shù)據(jù)庫的連接,包括:? 建立一個永久的數(shù)據(jù)庫連接。? 覆蓋默認(rèn)的服務(wù)器登錄。? 創(chuàng)建應(yīng)用程序級的 B D E別名。

34、? 控制事務(wù)并指定事務(wù)的隔離級別。.2.8.1.1.應(yīng)用程序級的連接使用 T D a t a b a s e組件的原因之一是,可以通過它建立一個應(yīng)用程序級的別名。與 B D E配置程序建立的別名不同的是,T D a t a b a s e組件建立的別名只在本項(xiàng)目中有效。如果要與其他應(yīng)用程序共享這個別名,可以把T D a t a b a se組件放到可共享的數(shù)據(jù)模塊( T D a t a M o d u l e )中,然后把數(shù)據(jù)模塊放到對象庫中,這樣,其他應(yīng)用程序就可以使用它了。要建立一個應(yīng)用程序級的別名,可以設(shè)置 T D a t a b a s e . D a t a b a s e N a

35、m e屬性。至于 T D a t a b as e 要連接的數(shù)據(jù)庫的 B D E別名則由 T D a t a b a s e . A l i a s N a m e屬性來指定。2.8.1.2.安全控制T D a t a b a s e 通過控制用戶的登錄過程來限制用戶對服務(wù)器數(shù)據(jù)的訪問。在登錄時,用戶必須給出合法的用戶名和口令才能訪問數(shù)據(jù)。默認(rèn)情況下,當(dāng)試圖連接數(shù)據(jù)庫時,會打開一個標(biāo)準(zhǔn)的對話框。處理登錄有幾種方式。首先,完全可以跳過登錄,讓用戶不需登錄就可以訪問服務(wù)器數(shù)據(jù)。其次,可以根據(jù)需要調(diào)出幾種不同的登錄對話框,以便在將用戶名和口令傳給服務(wù)器進(jìn)行正常的檢查之前進(jìn)行你自己的合法性檢查。最后,

36、可以允許用戶在不關(guān)閉應(yīng)用程序的情況下退出再重新登錄。下面將詳細(xì)介紹這些技術(shù)。2.8.1.2.1 自動登錄不讓登錄對話框出來如果不想出現(xiàn)登錄對話框,必須設(shè)置T D a t a b a s e的下列屬性:A l i a s N a m e設(shè)為一個已有的用 B D E 配置工具定義的 B D E別名,通常與 T Ta b l e、T Q u e r y組件的 A l i a s屬性相同。D a t a b a s e N a m e設(shè)為一個應(yīng)用程序級的別名,這個別名代表T Tab l e 、 T Q u e r y或T S t o r e P r o c組件要訪問的數(shù)據(jù)庫。這些組件將使用該值作為它們

37、的A l i a s屬性值。L o g i n P r o m p t設(shè)為 F a l s e,這樣, T D a t a b a s e組件將從 P a r a m s屬性中獲取用戶名和口令。 P a r a m s給出用戶名和口令。為此,必須打開一個字符串編輯器來設(shè)置這些值。設(shè)置了這些屬性后,必須把T Ta b l e、 T Q u e r y或 T S t o r e P r oc的A l i a s屬性值設(shè)為 T D a t a b a s e的D a t a b a s e -N a m e屬性值,這樣,就把這些數(shù)據(jù)集組件與T D a t a b a s e連接起來。現(xiàn)在,可以把 T

38、 D a t a b a s e . C o n n e c t e d的屬性設(shè)為 Tr u e 。這樣,當(dāng)應(yīng)用程序連接到服務(wù)器時,將不提示輸入用戶名和口令,因?yàn)镻 a r a m s屬性中已經(jīng)給出了用戶名和口令。.2.8.1.2.2 自定義的登錄對話框在某些場合,可能需要為用戶提供自定義的登錄對話框。例如,你可能想提示用戶在對話框中輸入除了用戶名和口令之外的附加信息,或者希望在程序開始時能出現(xiàn)更漂亮的登錄對話框, 而不是默認(rèn)的那種。 無論是何種情況, 處理都非常簡單。首先,把 T D a t a b a s e . L o g i n P r o m p t屬性設(shè)為 Tr u e ,這樣就不

39、會顯示默認(rèn)的登錄對話框,并保證觸發(fā) O n L o g i n事件。不過,現(xiàn)在不要通過 P a r a m s屬性提供用戶名和口令,而要編寫處理 T Da t a b a s e . O n L o g i n事件的處理過程 。這個事件處理過程在 T Da t a b a s e . C o n n e c t e d屬性和 T D a t a b a s e . L o g in P r o m p t被設(shè)為 Tr u e 時被調(diào)用。下面的函數(shù)自定義了一個登錄窗口,并返回用戶名和密碼:2.8.1.2.3 從當(dāng)前會話退出2.8.1.3 事務(wù)控制用Delphi 5 編寫的客戶程序可以通過 T D

40、 a t a b a s e 的有關(guān)屬性和方法來處理事務(wù)。下面將介紹怎樣在 Delphi 5 程序中處理事務(wù)。2.8.1.3.1 隱式和顯式的事務(wù)控制Delphi 5 既可以隱式又可以顯式地處理事務(wù),默認(rèn)是隱式的。隱式的事務(wù)是以逐行的方式開始和提交的。這意味著,當(dāng)調(diào)用P o s t 方法或 P os t 方法被 V C L 的代碼自動調(diào)用時,由于是逐行處理的,因此可能導(dǎo)致網(wǎng)絡(luò)流量增加,從而降低效率。顯式的事務(wù)處理又分下面兩種方式。一種方式是調(diào)用 T D a t a b a s e組件的 S t a r t Tr a n s a c t i on ( )、 C o m m i t ( )或R o

41、 l l B a c k ( )等方法;另一種方式是通過 T Q u e r y組件的直通 ( p a s s - t h r o u g h ) SQ L命令來實(shí)現(xiàn)的,由于顯式事務(wù)的網(wǎng)絡(luò)流量較小,而且代碼較安全,建議采用這種方式。.2.8.1.3.2 處理事務(wù)T D a t a b a s e的方法中有三個是與數(shù)據(jù)庫事務(wù)有關(guān)的,分別是:S t a rt Tran s a c t i o n ( )、C o m m i t ( )和 R o l l B a c k ( )。S t a r t Tr a n s a c t i o n ( )啟動一個事務(wù) ,隔離級別由 T D a ta b a

42、s e . Tr a n s I s o l a t i o n屬性指定。在調(diào)用 S t a r t Tra n -s a c t i o n ( )之后對數(shù)據(jù)庫所做的任何修改都成為事務(wù)的一部分。如果對數(shù)據(jù)庫的所有修改都成功,則調(diào)用T D a t a b a s e .C o m m it ( )方法把所有修改一次保存到數(shù)據(jù)庫中。反之,如果 發(fā)生了錯誤,則調(diào)用 T D a t a b a s e . R o l l B a c k ( )方法來取消所有的修改。2.8.1.3.3 SQL 直通模式S Q L 直通 ( p a s s - t h r o u g h )模式能夠使 Delphi 5

43、 數(shù)據(jù)庫應(yīng)用程序與 B D E共享到數(shù)據(jù)庫服務(wù)器的連接。 Delphi 5 的程序中如果調(diào)用了 BDE API,則可能需要使用 B D E連接。直通模式是在 B D E配置工具中設(shè)置的。這種模式有三個選項(xiàng):SHARED AUTO C O M M I T以逐行方式處理數(shù)據(jù)庫事務(wù),主要用于桌面數(shù)據(jù)庫應(yīng)用程序。在客戶 / 服務(wù)器環(huán)境下,這將導(dǎo)致網(wǎng)絡(luò)流量增加,因此不推薦這個選項(xiàng),但這是 Delphi 5 應(yīng)用程序的默認(rèn)選項(xiàng)。SHARED NOAUTO C O M M I T Delphi 5程序必須通過調(diào)用 T D a t a b a se的S t a r t Tr a n s a c t i o n

44、 ( )、 C o m m i t ( )和 R o l l Ba c k ( )方法來顯式地啟動、提交和回滾事務(wù)。NOT SHARED B D 和ET Q u e r y組件提交的直通 S Q L 語句不共享同一個連接。這意味著, S Q L 代碼可以不受 B D E功能的限制,可以發(fā)揮服務(wù)器的特性。如果不想使用直通式 S Q L但又想對事務(wù)進(jìn)行更多的控制,可以把這個選項(xiàng)設(shè)為 SHARED NOAUTOC O M M并I自T行處理事務(wù)。在大多數(shù)情況下,這種模式是可以的。但是,在多用戶環(huán)境下,如果某條記錄需要頻繁地更新,則可能發(fā)生沖突。2.8.1.3.4 隔離級別隔離級別是指一個事務(wù)對其他事務(wù)

45、正在訪問的數(shù)據(jù)具有怎樣的可見性。T D a ta b a s e . Tr a n s I s o l a t i o n屬性用于指定一個事務(wù)的隔離級別。對于 Tr a n s I s o l a t i o n屬性,可以有三種取值,分別代表三種隔離級別:t i D i r R e a d 最低的隔離級別。具有該級別的事務(wù)可以讀取其他事務(wù)正在修改但還沒有提交的數(shù)據(jù)。.t i R e a d C o m m i t t e d這是默認(rèn)的隔離級別。具有該級別的事務(wù)只能讀取那些已被其他事務(wù)提交的數(shù)據(jù)。t i R e p e a t a b l e R e a d這是最高的隔離級別。具有這種隔離級別的

46、事務(wù)無法讀到另一個事務(wù)正在讀取的數(shù)據(jù)。不同的服務(wù)器所支持的隔離級別也可能不同。 Delphi 5 通常使用 t i R e a d C o m m i t t e d 級別,除非服務(wù)器不支持該級別。2.8.2 TQuery比 TTable 優(yōu)秀有人認(rèn)為開發(fā)客戶 / 服務(wù)器結(jié)構(gòu)的前端與開發(fā)桌面數(shù)據(jù)庫應(yīng)用程序是相同或類似的,這是一個較為普遍的錯誤認(rèn)識。從使用 T Ta b l e還是 T Q u e r y的比較中,我們可以體會到這種區(qū)別。下面將討論使用 T Ta b l e組件的優(yōu)缺點(diǎn),分析在什么情況下應(yīng)該使用它、什么情況下不應(yīng)該使用它。通過這些分析,你將會理解為什么使用T Q u e r y組

47、件比較好。T Ta b l e組件能夠操作整個數(shù)據(jù)庫表、瀏覽前后的記錄或者轉(zhuǎn)到某個特定的記錄。不過,這些概念對 S Q L數(shù)據(jù)庫服務(wù)器來說則是不適用的 。關(guān)系型數(shù)據(jù)庫是以數(shù)據(jù)集的形式被訪問的。因此, S Q L 數(shù)據(jù)庫中沒有下一條記錄、前一條記錄和后一條記錄等概念。而在 T Ta b l e 組件中,這些概念是非常普遍的。盡管有些 S Q L數(shù)據(jù)庫提供了可滾動的指針,但這不是標(biāo)準(zhǔn)的,當(dāng)我們通過 T Ta b l e 組件操作 S Q L 數(shù)據(jù)庫時,最重要的一點(diǎn)就是, 通過 T Ta b l e 組件發(fā)出的數(shù)據(jù)庫操作命令必須轉(zhuǎn)換為 S Q L 代碼才能被 S Q L 數(shù)據(jù)庫識別和執(zhí)行。 這不僅限

48、制了對數(shù)據(jù)庫的訪問,而且也大大降低了效率。雖然 T Ta b l e 的 F i n d K e y ( )方法能夠搜索記錄,但對于 S Q L 數(shù)據(jù)庫來說此方法是有限制的。首先,F(xiàn) i n d K e y ( )只能基于定義了索引的字段進(jìn)行搜索,而 T Q u e r y則沒有這個限制,因?yàn)樗怯?S Q L 來查詢記錄的。盡管 TTable.FindKey( )最終還是用 S E L E C T 命令來對數(shù)據(jù)庫表進(jìn)行操作的,但是,使用 F i n d K e y ( )得到的結(jié)果集中包含了所有的字段,即使通過 T Ta b l e的字段編輯器只選擇了其中部分字段。.2.8.3 使用 TQu

49、ery 組件3使用 ADO摘自 Master Delphi7第 15章3.1Microsoft數(shù)據(jù)訪問組件(MDAC)3.2 使用 dbGo組件3.3 使用 Jet 引擎3.4 光標(biāo)ADO集合有兩個基礎(chǔ)屬性會對程序產(chǎn)生基礎(chǔ)性的影響, 并且不可分割的相互鏈接在一起,它們是: CursorLocation 和CursorType3.4.1 光標(biāo)位置CursorLocation 屬性運(yùn)行程序員來指定誰控制數(shù)據(jù)的提取和更新, 有兩個選擇:客戶機(jī)( clUseClient )和服務(wù)器( clUseServer )。所作的選擇會影響數(shù)據(jù)集合的功能、性能和可擴(kuò)張性。3.4.1.1 客戶端光標(biāo)( clUseClient )客戶端光標(biāo)由 ADOCursor Engine 負(fù)責(zé)管理,當(dāng)數(shù)據(jù)集打開的時候數(shù)據(jù)從服務(wù)器提取到客戶端,并保存在內(nèi)存中,由 ADO Cursor Engine 管理更新和操作.3.4.1.2 服務(wù)器端光標(biāo)( clUseServer )3.4.2 光標(biāo)類型3.4.2.1 只向前光標(biāo)3.4.2.2 靜態(tài)光標(biāo)3.4.2.3 鍵集光標(biāo)3.4.2.4 動態(tài)光標(biāo)3.4.3 要求與結(jié)果3.4.4 無記錄計(jì)數(shù)3.4.5 客戶端索引IndexFieldName ,ADO不從數(shù)據(jù)源讀數(shù),而是在內(nèi)存中完成的。3.4.6 復(fù)制Clone方法可以復(fù)

溫馨提示

  • 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)方式做保護(hù)處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負(fù)責(zé)。
  • 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請與我們聯(lián)系,我們立即糾正。
  • 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時也不承擔(dān)用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。

評論

0/150

提交評論