在開發(fā)ASP應(yīng)用程序時(shí),使用最多或者說是必不可少的,應(yīng)該是ADO組件了,因?yàn)樗遣倏v數(shù)據(jù)庫(kù)的重要手段。下面介紹ADO的使用方法及注意事項(xiàng)。
ADO,即Active Data Objects,實(shí)際是一種提供訪問各種數(shù)據(jù)類型的連接機(jī)制。ADO設(shè)計(jì)為一種極簡(jiǎn)單的格式,通過ODBC的方法同數(shù)據(jù)庫(kù)接口相連。用戶可以使用任何一種ODBC數(shù)據(jù)源,即不僅適合于SQL Server、Oracle、Access等數(shù)據(jù)庫(kù)應(yīng)用程序,也適合于Excel表格、文本文件、圖形文件和無格式的數(shù)據(jù)文件。ADO是基于OLE DB之上的技術(shù),因此ADO通過其內(nèi)部的屬性和方法提供統(tǒng)一的數(shù)據(jù)訪問接口方法。
ADO提供了一系列的類和方法,用來與數(shù)據(jù)庫(kù)建立連接,然后對(duì)數(shù)據(jù)庫(kù)中的數(shù)據(jù)進(jìn)行增、刪、改、查各種操作。下面分別介紹ADO中常用的幾個(gè)類。
Connection類具有以下功能。
l 建立數(shù)據(jù)庫(kù)連接。
l 執(zhí)行SQL語(yǔ)句。
l 執(zhí)行事務(wù)。
連接類(Connection)用來與數(shù)據(jù)庫(kù)建立連接。連接成功,Connection以對(duì)象的形式存在。應(yīng)用程序通過一個(gè)連接對(duì)數(shù)據(jù)庫(kù)進(jìn)行操作。在建立連接前,最主要的是需要設(shè)置連接字符串,用來指定連接數(shù)據(jù)庫(kù)所用的驅(qū)動(dòng)程序、數(shù)據(jù)源名稱、用戶名和密碼等。Connection類常用的屬性與方法如下。
l ConnectionString屬性:連接字符串,在打開連接前需要設(shè)置。
l ConnectionTimeout和Mode屬性:超時(shí)時(shí)間和連接模式,一般在打開連接前也需要設(shè)置。
l CursorLocation屬性:設(shè)置或者返回游標(biāo)位置。
l DefaultDatabase屬性:為連接指定一個(gè)默認(rèn)的數(shù)據(jù)庫(kù)。
l IsolationLevel屬性:確定事務(wù)(Transaction)在連接的隔離等級(jí)。
l Provider屬性:為連接指定一個(gè)驅(qū)動(dòng)程序,可以包括在ConnectionString中。
l Version屬性:返回ADO的版本。
l Open和Close方法:建立和中斷一個(gè)連接。
l Execute方法:在連接上執(zhí)行命令,比如執(zhí)行一條SQL語(yǔ)句。
l BeginTrans、CommitTrans和RollbackTrans方法:用來管理事務(wù)。
l Errors對(duì)象:數(shù)據(jù)源返回的錯(cuò)誤信息。
CursorLocation屬性取值的含義如下。
l adUseServer:它可以隨時(shí)反映數(shù)據(jù)庫(kù)服務(wù)器上的改動(dòng),但是系統(tǒng)開銷很大。
l adUseClient:沒有實(shí)時(shí)性,但可以對(duì)數(shù)據(jù)做再排序、篩選等操作。
如果對(duì)數(shù)據(jù)的實(shí)時(shí)性沒有要求的話,建議盡量用adUseClient,以提高性能。
創(chuàng)建連接是操縱數(shù)據(jù)庫(kù)的第一步,也是數(shù)據(jù)庫(kù)優(yōu)化時(shí)大有文章可做之處,有效地管理數(shù)據(jù)庫(kù)的連接,可以極大地提高應(yīng)用程序的效率,這里就關(guān)于Connection的合理使用做一個(gè)簡(jiǎn)單的小結(jié),詳細(xì)的原理見本書“創(chuàng)建高性能的ASP應(yīng)用程序”一章中關(guān)于ADO優(yōu)化的相關(guān)內(nèi)容。
l 使用OLE DB驅(qū)動(dòng)程序,使用連接池。
l 使用前再創(chuàng)建連接,使用后立即關(guān)閉連接,釋放對(duì)象(其實(shí)這里關(guān)閉連接是將用后的連接立即放入連接池中)。
l 絕對(duì)不要將連接存放在Application或Session中。
l 如果沒有返回記錄集,在Execute的參數(shù)中要加上adExecuteNoRecords,如:
cnn.Execute strSQL,,adCmdText + adExecuteNoRecords
Command類具有以下功能。
l 預(yù)編譯SQL語(yǔ)句。
l 執(zhí)行SQL語(yǔ)句。
l 執(zhí)行存儲(chǔ)過程。
l 快速返回整個(gè)表的內(nèi)容。
命令類(Command)定義了對(duì)數(shù)據(jù)庫(kù)的一系列操作。使用命令行對(duì)象來查詢數(shù)據(jù)庫(kù)并返回?cái)?shù)據(jù)集(Recordset)對(duì)象形式的查詢結(jié)果。命令類在操縱數(shù)據(jù)庫(kù)前需要與一個(gè)已經(jīng)打開的連接對(duì)象(Connection)建立關(guān)聯(lián)。Command類常用的屬性與方法如下。
l ActiveConnection屬性:將一個(gè)命令行對(duì)象與一個(gè)打開的連接關(guān)聯(lián)。
l CommandText屬性:定義命令行的內(nèi)容,比如SQL語(yǔ)句等。
l CommandType屬性:指定命令的類型。
l CommandTimeout屬性:指定服務(wù)器等待一條命令執(zhí)行的時(shí)間。
l Execute方法:執(zhí)行命令行并返回一個(gè)數(shù)據(jù)集(Recordset)對(duì)象。
|
讀者也許已經(jīng)注意到了,Connection和Command類都有各自的Execute方法,都可以用來執(zhí)行一條SQL語(yǔ)句,從這方面來講,二者的差別不大。但Command類功能更為強(qiáng)大,通過指定CommandType屬性,還可以執(zhí)行存儲(chǔ)過程等其他操作。 |
提高數(shù)據(jù)庫(kù)的操縱性能,除了提高數(shù)據(jù)庫(kù)的連接性能外,還可以提高對(duì)數(shù)據(jù)的操縱性能,Command類正是為此而設(shè)計(jì)的。這里就關(guān)于Command的合理使用做一個(gè)簡(jiǎn)單的小結(jié),詳細(xì)的原理見本書“創(chuàng)建高性能的ASP應(yīng)用程序”章中關(guān)于ADO優(yōu)化的相關(guān)內(nèi)容。
l 合理設(shè)置CommandType屬性,以提高執(zhí)行效率,不建議使用adCmdUnknown。
l 如果沒有返回記錄集,在CommandType屬性上要加上adExecuteNoRecords。
l 如果需要重復(fù)的執(zhí)行類似的SQL語(yǔ)句,可以先將它預(yù)編譯,提高的效率也很可觀。
Recordset類具有以下功能。
l 存放檢索結(jié)果。
l 操縱數(shù)據(jù),對(duì)數(shù)據(jù)進(jìn)行增、刪、改操作。
l 對(duì)數(shù)據(jù)再排序。
數(shù)據(jù)集類(Recordset)定義了從數(shù)據(jù)庫(kù)返回的一系列記錄的集合。通過數(shù)據(jù)集可以對(duì)記錄及組成記錄的列進(jìn)行各種操作。Recordset類常用屬性與方法如下。
l RecordCount屬性:返回記錄集中記錄的條數(shù)。
l LockType屬性:對(duì)記錄集的鎖定方式,詳見下面表2-8中的說明。
l CursorType屬性:記錄集中游標(biāo)類型,詳見下面表2-9中的說明。
l BOF、EOF屬性:返回記錄集中游標(biāo)的當(dāng)前位置是否是記錄集的頭或尾。
l MoveNext、MovePre:將記錄集中的游標(biāo)向后、前移動(dòng)一個(gè)位置。
l MoveFirst、MoveNext:將記錄集中的游標(biāo)移動(dòng)到最前或最后。
表2-8是屬性LockType的取值。
表2-8 屬性LockType的取值
名 稱 |
解 釋 |
adLockReadOnly |
=1,默認(rèn)值,表示以只讀方式打開記錄集,因而無法更改數(shù)據(jù),在這種情況下使用AddNew方法就會(huì)發(fā)生錯(cuò)誤 |
adLockPessimistic |
=2,保守式記錄鎖定(逐條)。采用在調(diào)用Update方法時(shí)立即鎖定數(shù)據(jù)源的方式。此時(shí),其他用戶不能訪問該數(shù)據(jù) |
adLockOptimistic |
=3,開放式記錄鎖定(逐條)。只在調(diào)用 Update 方法時(shí)鎖定記錄 |
adLockBatchOptimistic |
=4,開放式批更新。用于成批更新數(shù)據(jù),與UpdateBatch方法相對(duì)應(yīng) |
|
以上的=1表示其常量值是1,依此類推。 |
表2-9是屬性CursorType的取值。
表2-9 屬性CursorType的取值
名 稱 |
解 釋 |
adOpenForwardOnly |
=0,僅向前游標(biāo),默認(rèn)值,只能在記錄中向前滾動(dòng)。這可以節(jié)省資源并提高性能 |
adOpenStatic |
=3,靜態(tài)游標(biāo)??梢杂脕聿檎覕?shù)據(jù)或生成報(bào)告的記錄集合的靜態(tài)副本。另外,對(duì)其他用戶所做的添加、更改或刪除不可見。推薦在ASP中只使用這兩種游標(biāo) |
adOpenKeyset |
=1,鍵集游標(biāo)。鍵集游標(biāo)與動(dòng)態(tài)游標(biāo)相似,不同的只是禁止查看其他用戶添加的記錄,并禁止訪問其他用戶刪除的記錄,其他用戶所做的數(shù)據(jù)更改將依然可見 |
adOpenDynamic |
=2,動(dòng)態(tài)游標(biāo)。可以看見其他用戶所做的添加、更改和刪除。允許在記錄集中進(jìn)行所有類型的移動(dòng) |
|
以上的=0表示其常量值是0,依此類推。 |
當(dāng)Recordset對(duì)象有效時(shí),可以使用如例程2-4的方式來獲得當(dāng)前記錄某一字段的值。其中“Name_S”是數(shù)據(jù)表中的字段名。
例程2-4 獲得Recordset對(duì)象當(dāng)前記錄中某一字段的值
Dim rs
Dim strName as String
……
strName = rs("Name_S").Value
……
RecordSet是專門為數(shù)據(jù)操縱而設(shè)計(jì)的,它可以接收Connection和Command類的檢索結(jié)果,也可以自己向數(shù)據(jù)庫(kù)發(fā)出檢索命令。如果說Command類側(cè)重在數(shù)據(jù)庫(kù)方面做優(yōu)化的話,那么RecordSet專門在用戶對(duì)檢索結(jié)果的處理上做優(yōu)化。這里就關(guān)于RecordSet的合理使用做一個(gè)簡(jiǎn)單的小結(jié),詳細(xì)的原理見本書“創(chuàng)建高性能的ASP應(yīng)用程序”一章中關(guān)于ADO優(yōu)化的相關(guān)內(nèi)容。
l 合理設(shè)置LockType的值,如果只是查看結(jié)果,設(shè)其值為adLockReadOnly即可。
l 合理設(shè)置CursorType的值,如果只用到MoveNext,則設(shè)其值為adOpenForwardOnly。
l 如果對(duì)數(shù)據(jù)的實(shí)時(shí)性沒有要求的話,盡量用adUseClient。
l 只有當(dāng)CursorType設(shè)為adOpenKeyset或adOpenStatic時(shí),RecordCount才有效。
[NextPage]
在早些年,有人曾推薦使用adovbs.txt這個(gè)文件,以訪問 ADO 的各種常量。在要使用常量的每個(gè)頁(yè)面中必須包含此文件。此常量文件相當(dāng)大,增加了每個(gè) ASP 頁(yè)面的編譯時(shí)間和腳本大小,而且編程也比較煩瑣。
IIS 5.0 引入了綁定到組件類型庫(kù)的功能。只需要引用類型庫(kù)一次,便可將其應(yīng)用在每個(gè) ASP 頁(yè)面上。每個(gè)頁(yè)面不再產(chǎn)生編譯常量文件的開銷,而且開發(fā)人員不必在每個(gè)ASP文件中都用include加入那個(gè)龐大的文件了。
要訪問ADOTypeLib,只需在global.asa文件中加入相應(yīng)的引用即可,有以下兩種途徑:
<!-- METADATA NAME="Microsoft ActiveX Data Objects 2.5 Library"
TYPE="TypeLib" UUID="{00000205-0000-0010-8000-00AA006D2EA4}" -->
或
<!-- METADATA TYPE="TypeLib"
FILE="C:\Program Files\Common Files\system\ado\msado15.dll" -->
|
這種方法當(dāng)然也適用于對(duì)其他COM的引用,如CDO庫(kù),或其他自己開發(fā)的COM。 |
使用ADO操縱數(shù)據(jù)庫(kù)一般可以分為以下幾步。
(1)創(chuàng)建一個(gè)到數(shù)據(jù)源的連接(Connection),連接到數(shù)據(jù)庫(kù);或者開始一個(gè)事務(wù)(Transaction)。
(2)組織一條SQL語(yǔ)句,此SQL語(yǔ)句中即可進(jìn)行插入、修改和刪除等任何數(shù)據(jù)庫(kù)操作,只要你與數(shù)據(jù)庫(kù)建立連接時(shí)所使用的用戶有足夠的權(quán)限。
(3)執(zhí)行SQL語(yǔ)句。
(4)如果SQL語(yǔ)句中使用的是SELECT語(yǔ)句,則可以將返回的數(shù)據(jù)保存在數(shù)據(jù)集對(duì)象Recordset中,以便進(jìn)一步操作數(shù)據(jù)。
(5)通過數(shù)據(jù)集對(duì)象對(duì)數(shù)據(jù)進(jìn)行各種操作,包括獲取某一字段值,以及修改、增加、刪除記錄等。
(6)如果使用數(shù)據(jù)集對(duì)象Recordset對(duì)數(shù)據(jù)庫(kù)進(jìn)行了增、刪、改的操作,最后必須更新數(shù)據(jù)源,如果使用事務(wù),確認(rèn)是否接受事務(wù)期間發(fā)生的數(shù)據(jù)變化。
(7)結(jié)束連接和事務(wù)。
|
使用SQL語(yǔ)句和使用數(shù)據(jù)集對(duì)象Recordset都可以向數(shù)據(jù)庫(kù)中增加、修改、刪除記錄,兩種方法可以說是殊途同歸。使用Recordset操作似乎更簡(jiǎn)單一些,例如不需要處理字符串中的單引號(hào)問題等,但使SQL語(yǔ)句功能更為強(qiáng)大且通用。它除了可以操縱數(shù)據(jù)記錄以外,還可以操作表、用戶等。筆者在這里建議使用SQL語(yǔ)句來操縱數(shù)據(jù)記錄,這樣讀者將來在使用其他技術(shù)開發(fā)數(shù)據(jù)庫(kù)時(shí),比如PHP、JSP等,會(huì)覺得非常順暢。 |
下面通過實(shí)例的方式說明在Visual Basic中如何使用ADO與數(shù)據(jù)庫(kù)建立連接并操縱數(shù)據(jù)庫(kù)。
例程2-5完成了與數(shù)據(jù)庫(kù)建立連接與關(guān)閉連接?;舅悸肪褪窍仍O(shè)置連接類Connection的必要屬性,尤其是連接字符串ConnectionString,然后調(diào)用Connection類的Open方法打開連接,并將其保存在全局變量g_Conn中,以便在其他地方使用。GxcDBType定義為枚舉類型,用來表示是連接到Access數(shù)據(jù)庫(kù)還是SQL Server數(shù)據(jù)庫(kù)。
例程2-5 建立與關(guān)閉數(shù)據(jù)庫(kù)連接
<%
'更改數(shù)據(jù)庫(kù)名字
db="database/database.mdb"
Set objConn = Server.CreateObject("ADODB.Connection")
objConn.ConnectionString="Provider=Microsoft.Jet.OLEDB.4.0; &_
Data Source=" & Server.MapPath(db)
'如果你的服務(wù)器采用較老版本Access驅(qū)動(dòng),請(qǐng)用下面的連接方法
'objConn.ConnectionString="driver={Microsoft Access Driver (*.mdb)}; &_
dbq=" & Server.MapPath(db)
objConn.Open
Function CloseDatabase
objConn.close
Set objConn = Nothing
End Function
%>
與數(shù)據(jù)庫(kù)建立連接后,下面便可以操縱數(shù)據(jù)庫(kù)中的數(shù)據(jù)了。例程2-6是使用Connection類的Execute方法來執(zhí)行一條SQL語(yǔ)句并將返回保存在Recordset中的示例。例程中的“TypeName”表示數(shù)據(jù)庫(kù)中的某一字段名。
例程2-6 使用Connection對(duì)象操縱數(shù)據(jù)庫(kù)
<%
'按輸入的參數(shù)查詢,并返回一個(gè)集合類
Dim strSQL
Dim strName
'構(gòu)造SQL語(yǔ)句
strSQL = "Select * from ClientType "
Dim rs
Set rs = g_Conn.Execute(strSQL)
'往集合中添加查詢結(jié)果
Dim i
For i = 1 To rs.RecordCount
strName = rs("TypeName").Value
rs.MoveNext
Next i
Set rs = Nothing
%>
至此,關(guān)于ADO使用的基本知識(shí)就介紹完了,讀者可以在以下幾章的學(xué)習(xí)中來體會(huì)和實(shí)踐ADO操縱數(shù)據(jù)庫(kù)的一些技巧。
如對(duì)本文有疑問,請(qǐng)?zhí)峤坏浇涣髡搲?,廣大熱心網(wǎng)友會(huì)為你解答?。?點(diǎn)擊進(jìn)入論壇