直播中
strConn = "Provider=SQLOLEDB; Data Source=WATCHER; " & _
"Initial Catalog=pubs; User Id=davids; Password=whisky"
Set Application("ConnectionString") = strConn
End Sub
在ASP頁(yè)面中,可以使用下面的代碼:
Set conPubs = Server.CreateObject("ADODB.Connection")
conPubs.Application("ConnectionString")
從個(gè)人的角度,我更喜歡使用包含文件的方法,因?yàn)槲覍懥嗽S多不同的連接到各種服務(wù)器和數(shù)據(jù)庫(kù)的例子。使用應(yīng)用程序方法將意味著每次必須關(guān)閉瀏覽器重新啟動(dòng)應(yīng)用程序。讀者可以使用自己喜歡的任一種方法,在速度上它們并沒(méi)有差別。
對(duì)于在本書的這節(jié)內(nèi)的例子,將使用一個(gè)含有連接字符串的connection.asp文件人作為一個(gè)包含文件。
8.3.4 連接語(yǔ)法
上面所敘述的是相關(guān)理論,當(dāng)確實(shí)要與數(shù)據(jù)存儲(chǔ)連接時(shí),應(yīng)該怎么辦?如果使用顯式定義的Connection對(duì)象,可以使用Open方法,它的語(yǔ)法如下:
connection.Open [ConnectionString], [UserID], [Password], [Options]
參數(shù)如表8-1所示:
表8-1 Open方法的參數(shù)及說(shuō)明
參 數(shù)
說(shuō) 明
ConnectionString
包含連接細(xì)節(jié)的字符串??梢允荗DBC DSN的名稱、數(shù)據(jù)鏈接文件的名稱或真實(shí)的連接細(xì)節(jié)
UserID
連接期間,用戶使用的名字。覆蓋連接字符串中提供的任何用戶名
Password
用戶的口令。覆蓋連接字符串中提供的任何口令
Options
可以是adAsyncConnect,指定異步地建立連接。忽略這個(gè)參數(shù),則建立一個(gè)同步連接
異步連接不用于ASP環(huán)境,因?yàn)槟_本語(yǔ)言不能接收來(lái)自ADO的事件。
8.3.5 連接的例子
下面是幾個(gè)示例,這里假定strConn包含一個(gè)有效的連接字符串。
為了打開(kāi)一個(gè)連接,使用Connection對(duì)象的Open方法。例如:
Set conPubs = Server.Connection("ADODB.Connection")
conPubs.Open strConn
' Some processing
conPubs.Close
也可以使用ConnectionString屬性:
Set conPubs = Server.CreateObject("ADODB.Connection")
conPubs.ConnectionString = strConn
conPubs.Open
' Some processing
conPubs.Close
這兩種實(shí)現(xiàn)方法之間沒(méi)有什么區(qū)別,如果使用前一種方法來(lái)實(shí)現(xiàn)連接,ConnectionString屬性同時(shí)也被賦值。
值得注意的是,一旦與數(shù)據(jù)存儲(chǔ)建立了連接,ADO可能會(huì)改變ConnectionString屬性值。不必?fù)?dān)心,ADO只填寫一些額外的屬性值。
8.3.6 連接緩沖池
連接緩沖池(connection pool)總使許多人感到困惑,其實(shí)原理非常簡(jiǎn)單。當(dāng)關(guān)閉一個(gè)連接,就用戶(和ADO)而言,這個(gè)連接已經(jīng)關(guān)閉。但實(shí)際上OLE DB并沒(méi)有關(guān)閉這個(gè)連接,只是將其放入了非活動(dòng)的連接緩沖池中。任何時(shí)候用戶(或其他人)打開(kāi)一個(gè)連接,OLE DB首先檢測(cè)連接緩沖池中是否有相同連接細(xì)節(jié)的連接存在。如果有,將直接從緩沖池中取得此連接。如果沒(méi)有,則為用戶創(chuàng)建一個(gè)新的連接。為了避免浪費(fèi)資源,經(jīng)過(guò)一段缺省的時(shí)間段后,就從緩沖池中清除該連接。
那么,它的優(yōu)點(diǎn)在哪里?打開(kāi)一個(gè)連接可能是所進(jìn)行的操作中最慢的操作之一,連接緩沖池使用戶能與數(shù)據(jù)存儲(chǔ)再次連接而無(wú)須重新創(chuàng)建連接。這對(duì)于那些連續(xù)打開(kāi)和關(guān)閉大量連接的Web站點(diǎn)顯得特別重要。
對(duì)于ODBC連接,連接緩沖池由ODBC Data Source Administrator控制。對(duì)于OLE DB,不能改變連接緩沖池(或叫會(huì)話緩沖池)。
必須注意的是,連接緩沖池不是連接共享。一個(gè)連接只有在被客戶關(guān)閉后才能再次使用。
內(nèi)務(wù)處理
為了使連接緩沖池生效,必須確保內(nèi)務(wù)處理(Housekepping)處于有序狀態(tài)。這包括及時(shí)關(guān)閉Connection對(duì)象,這樣它們才能回到緩沖池重新使用。你可能認(rèn)為不斷地打開(kāi)、關(guān)閉連接對(duì)系統(tǒng)的開(kāi)銷很大,但必須衡量一下可擴(kuò)展性——你的應(yīng)用程序可能有許多人在使用,OLE DB又非常善于管理連接資源。
一般的原則是:盡可能晚地建立連接,同時(shí)又要盡可能早地關(guān)閉連接,這樣保證連接打開(kāi)的時(shí)間段最短。
8.4 記錄集
前面已經(jīng)提到,記錄集是ADO中最常用的對(duì)象,這并不值得奇怪。畢竟,他們包含著數(shù)據(jù)。但是,對(duì)于記錄集還有比想象的更多的內(nèi)容,知道數(shù)據(jù)如何保存和處理很重要,因?yàn)檫@為選擇使用哪種記錄集提供了更多的參考。
記錄集有不同的類型,在一些細(xì)小的地方存在著差異,很容易造成失誤。首先需要認(rèn)真談?wù)摰氖枪鈽?biāo)的概念。
8.4.1 光標(biāo)
光標(biāo)(cursor)是讓許多人感到困惑的概念,但實(shí)際上非常的簡(jiǎn)單。
光標(biāo)用來(lái)管理記錄集和記錄集的當(dāng)前位置,后者是由當(dāng)前記錄指針來(lái)處理的。
這不是Recordset對(duì)象所做的嗎?是的,但是記錄集也是依靠它的光標(biāo)。這仍然沒(méi)有回答光標(biāo)是什么這個(gè)問(wèn)題,那么先來(lái)看一個(gè)記錄集,如表8-2所示:
AU_ID
AU_LNAME
AU_FNAME
PHONE
172-32-1176
White
Bob
408 496-7223
219-46-8915
Green
Marjorie
415 986-7020
238-95-7766
Carson
Cheryl
415 548-7723
267-41-2394
O'Leary
Michael
408 286-2428
274-80-9391
Straight
Dean
415 834-2919
341-22-1782
Smith
Meander
913 843-0462
這里有六行四列。打開(kāi)一個(gè)記錄集,當(dāng)前記錄就是第一個(gè)記錄,即為Bob White的那條記錄。用什么來(lái)標(biāo)識(shí)當(dāng)前記錄?用當(dāng)前記錄指針。那么又如何處理這個(gè)指針呢?當(dāng)需要移到下一條記錄或者是其他記錄時(shí),是通過(guò)光標(biāo)來(lái)實(shí)現(xiàn)的。在訪問(wèn)當(dāng)前行的字段時(shí),光標(biāo)知道目前位于哪一行,所以能返回正確的值。如果試圖移出記錄集的最后一行,光標(biāo)也會(huì)處理。
理解光標(biāo)的一種好方法是將光標(biāo)想象成為一個(gè)可以在記錄集內(nèi)移動(dòng)的窗口。這一窗口與記錄集的單個(gè)行同樣高,同樣長(zhǎng),因此一次只能看到一行數(shù)據(jù)值。當(dāng)你移到另一條記錄時(shí),這個(gè)窗口也跟著移動(dòng)。
也許你認(rèn)為這相當(dāng)簡(jiǎn)單,但它確實(shí)很重要,因?yàn)槟苡霉鈽?biāo)做什么是由光標(biāo)的類型決定的。
1. 光標(biāo)類型
光標(biāo)的類型標(biāo)識(shí)了光標(biāo)所能夠提供的功能。這里有四種類型的光標(biāo):
· 靜態(tài)(adOpenStatic)。靜態(tài)光標(biāo)含有對(duì)記錄的靜態(tài)拷貝。這意味著在記錄集建立之后,記錄集的內(nèi)容就固定了。其他用戶對(duì)記錄的更改、添加和刪除都是不可見(jiàn)的。允許在記錄集中向前、向后移動(dòng)。
· 只許前移(adOpenForwardOnly)。缺省的光標(biāo)類型,除了只允許向前移動(dòng)外,其余的與靜態(tài)光標(biāo)相同。
· 動(dòng)態(tài)(adOpenDynamic)。動(dòng)態(tài)的光標(biāo)沒(méi)有固定的記錄集。其他用戶的更改、添加或刪除操作在記錄集中是可見(jiàn)的。允許在記錄集中向前、向后移動(dòng)。
· 鍵集(adOpenKeyset)。鍵集類型的光標(biāo)除了記錄集是固定的,其余的與動(dòng)態(tài)光標(biāo)相似??梢钥吹狡渌脩舻男薷模掠涗泤s不可見(jiàn)。如果別的用戶刪除了記錄,那么這些記錄在記錄集中將會(huì)變得不可訪問(wèn)。這項(xiàng)功能是通過(guò)標(biāo)識(shí)記錄集的鍵來(lái)實(shí)現(xiàn)的,所以鍵一直保留著,即使改變或刪除記錄。
為了理解這些概念,再想象光標(biāo)窗口。對(duì)于只許前移的光標(biāo),可以看作是一個(gè)位于單向齒輪上的窗口,只能向前移動(dòng)。這一特點(diǎn)的有利之處在于一旦通過(guò)了一條記錄,光標(biāo)就會(huì)完全忘記該記錄,因?yàn)橛肋h(yuǎn)不會(huì)回到該記錄上。靜態(tài)光標(biāo)則移去了單向齒輪,允許向后移動(dòng);因?yàn)橐材芟蚝笠苿?dòng),光標(biāo)需要跟蹤這些記錄。由于這個(gè)原因,靜態(tài)光標(biāo)比只許前移的光標(biāo)慢。
對(duì)于鍵集和動(dòng)態(tài)類型的光標(biāo),窗口可以前后移動(dòng),但所看到的內(nèi)容可能會(huì)改變。鍵集光標(biāo)可以看到別人對(duì)數(shù)據(jù)的更改,但看不到新的或已刪除的記錄。因此,記錄集是固定的,但不是內(nèi)容固定。動(dòng)態(tài)光標(biāo)將它擴(kuò)展了,不僅可以改變記錄的內(nèi)容,而且可以改變記錄集。所以在動(dòng)態(tài)光標(biāo)中能夠看到有新的記錄出現(xiàn),同時(shí)刪除的記錄從記錄集中消失。
使用的光標(biāo)類型取決于想達(dá)到的目的。如果只想瀏覽記錄,也許是為了創(chuàng)建一個(gè)表格或一個(gè)選擇列表,那么用只許前移的光標(biāo)是最好不過(guò)了。雖然使用其他類型的光標(biāo)速度可能會(huì)慢一些,但也可以正常工作。
光標(biāo)的類型會(huì)影響性能,特別是服務(wù)器光標(biāo)。例如,在微軟的SQL Server 6.5中,鍵集和靜態(tài)類型的光標(biāo)都需要在臨時(shí)數(shù)據(jù)庫(kù)(tempdb)中放入一個(gè)完整的數(shù)據(jù)拷貝。其中,鍵集類型的光標(biāo)相比較而言稍微高效一些,因?yàn)樗粚㈡I拷入臨時(shí)數(shù)據(jù)庫(kù)。對(duì)于SQL Server 7.0情況不是這樣,不同類型的光標(biāo)的運(yùn)行效率差別不是很大。
2. 光標(biāo)位置
既然已經(jīng)解釋了什么是光標(biāo),以及光標(biāo)如何管理數(shù)據(jù),但是光標(biāo)在哪里呢?答案不是固定的,因?yàn)楣鈽?biāo)依賴于數(shù)據(jù)存儲(chǔ)。某些數(shù)據(jù)存儲(chǔ),比如微軟的SQL Server,有自身的光標(biāo)服務(wù);而別的如微軟的Access卻沒(méi)有光標(biāo)服務(wù)。
當(dāng)打開(kāi)一個(gè)記錄集時(shí),必須選擇是否希望數(shù)據(jù)存儲(chǔ)管理光標(biāo),或是希望OLE DB和ADO在本地為你管理光標(biāo)。后者可以實(shí)現(xiàn)是因?yàn)镺LE DB有其自己的光標(biāo)服務(wù)。通過(guò)使用Connection對(duì)象或Recordset對(duì)象的CursorLocation屬性可以設(shè)置這兩個(gè)選項(xiàng)??梢栽O(shè)定該屬性的值為:
· adUseServer:讓數(shù)據(jù)存儲(chǔ)管理光標(biāo)。
· adUseClient:讓ADO管理光標(biāo)。
可以在打開(kāi)連接或記錄集之前設(shè)置這個(gè)屬性:
conPubs.CursorLocation = adUseServer
conPubs.Open strConn
或者:
rsAuthors.CursorLocation = adUseClient
rsAuthors.Open "authors", conPubs
缺省的光標(biāo)是基于服務(wù)器的,理解這兩種類型的區(qū)別非常重要。對(duì)于一個(gè)服務(wù)器光標(biāo)來(lái)說(shuō),數(shù)據(jù)存儲(chǔ)的任務(wù)是管理記錄,所以,當(dāng)使用服務(wù)器光標(biāo)建立一個(gè)記錄集時(shí),數(shù)據(jù)存儲(chǔ)管理著記錄的移動(dòng)、記錄的更新等等。
對(duì)于一個(gè)客戶光標(biāo),記錄集的全部?jī)?nèi)容復(fù)制給客戶,受本地客戶光標(biāo)服務(wù)管理。這意味著對(duì)于一個(gè)客戶光標(biāo),打開(kāi)一個(gè)具有大量記錄的記錄集要比使用基于服務(wù)器的光標(biāo)打開(kāi)相同記錄集所花費(fèi)的時(shí)間長(zhǎng)得多。也需要使用基于客戶的光標(biāo)的時(shí)候,在本書后面,研究組件時(shí),會(huì)看到更多的相關(guān)的例子。
3. “消防帶”光標(biāo)
你可能知道“消防帶”(Firehose)光標(biāo),由于能給應(yīng)用程序帶來(lái)高的運(yùn)行效率,所以對(duì)其進(jìn)行解釋顯得非常重要。因?yàn)椤跋缼А惫鈽?biāo)是一種特殊類型的光標(biāo),只有在與微軟的SQL Server連接時(shí)才出現(xiàn)。SQL Server創(chuàng)建用戶請(qǐng)求的數(shù)據(jù)集,然后把數(shù)據(jù)直接傳給客戶以使其盡可能快地得到數(shù)據(jù)。SQL Server自身幾乎沒(méi)有光標(biāo)管理,這意味著它可以更快地處理數(shù)據(jù)。也就是說(shuō)數(shù)據(jù)可以在非常短的時(shí)間內(nèi)迅速返回到客戶端。從客戶方看,類型于只許前移的光標(biāo)。
那么,在前面討論光標(biāo)類型時(shí),為什么沒(méi)有涉及到“消防帶”光標(biāo)呢?因?yàn)檫@類光標(biāo)專用于SQL Server,并僅用于使用基于服務(wù)器的光標(biāo)時(shí)。這不是一種真正的光標(biāo)類型,獲得一個(gè)“消防帶”類型光標(biāo)的方法就是不指定光標(biāo)的類型。
8.4.2 鎖定
我們已經(jīng)解釋了光標(biāo)和如何管理數(shù)據(jù)。現(xiàn)在可以創(chuàng)建記錄集了嗎?恐怕還不行,因?yàn)檫€有一個(gè)問(wèn)題沒(méi)有討論,那就是鎖定。
鎖定就是如何確保數(shù)據(jù)的完整性,確保更改不會(huì)被覆蓋。我們需要避免的典型情況是多次更新,比如一個(gè)用戶改動(dòng)了一些數(shù)據(jù),接著另一個(gè)用戶立即又將其做了修改。為了對(duì)這種情況加以保護(hù),要鎖定記錄,有許多不同的方法可以保證記錄得到保護(hù)。可通過(guò)鎖定類型來(lái)設(shè)置這些方法。
鎖定類型
鎖定類型決定更新記錄時(shí)記錄是否或如何被鎖定。有四種類型的鎖定:
· 只讀(adLockReadOnly):缺省鎖定類型,記錄集是只讀的,不能修改記錄。
· 悲觀的(adLockPessimistic):當(dāng)修改記錄時(shí),數(shù)據(jù)提供者將嘗試鎖定記錄以確保成功地編輯記錄。只要編輯一開(kāi)始,則立即鎖住記錄。
· 樂(lè)觀的(adLockOptimistic):直到用Update方法提交更新記錄時(shí)才鎖定記錄。
· 批量樂(lè)觀的(adLockBatchOptimistic):允許修改多個(gè)記錄,只有調(diào)用UpdateBatch方法后才鎖定記錄。
當(dāng)不需要改動(dòng)任何記錄時(shí),應(yīng)該使用只讀的記錄集,這樣提供者不用做任何檢測(cè)。對(duì)于一般的使用,樂(lè)觀的鎖定可能是最好的選擇,因?yàn)橛涗浿槐绘i定一小段時(shí)間,數(shù)據(jù)在這段時(shí)間被更新。這減少了資源的使用。
悲觀的鎖定提高了數(shù)據(jù)的完整性,但卻是以犧牲并發(fā)性為代價(jià)的。并發(fā)性是許多用戶在同一時(shí)間查閱數(shù)據(jù)的能力。鎖定的記錄對(duì)其他用戶是不可見(jiàn)的,因而數(shù)據(jù)的并發(fā)性降低了。樂(lè)觀的鎖定只在一小段時(shí)間內(nèi)鎖定記錄,所以增強(qiáng)了數(shù)據(jù)的并發(fā)性,但同時(shí)其他用戶修改數(shù)據(jù)的幾率也增加了。
關(guān)于并發(fā)性和鎖定的問(wèn)題在微軟出版的《Inside SQL Server 7.0》(作者Ron Soukup和Kalen Delaney)中做了較好的論述。這是一本很有權(quán)威的專著,所以無(wú)論如何應(yīng)購(gòu)買這本專著,該書有大量的有價(jià)值的資料。
來(lái)源: