ASP 3.0高級編程(410)
發(fā)表時間:2023-08-07 來源:明輝站整理相關(guān)軟件相關(guān)文章人氣:
[摘要]8.5.1 Errors集合 Errors集合包含由單個ADO命令的執(zhí)行而引起的每一個錯誤的Error對象。使用Errors集合的原因是由于在一個命令的執(zhí)行過程中,可能會引起多個錯誤,O...
8.5.1 Errors集合
Errors集合包含由單個ADO命令的執(zhí)行而引起的每一個錯誤的Error對象。使用Errors集合的原因是由于在一個命令的執(zhí)行過程中,可能會引起多個錯誤,OLE DB提供者需要提供一種方式通知客戶方已有多個錯誤發(fā)生。
關(guān)于Errors集合有兩個重要的地方需要注意:
· 每次執(zhí)行ADO命令,如果發(fā)生錯誤,就清空錯誤集,同時代之以新的錯誤內(nèi)容。當(dāng)然,如果沒有錯誤發(fā)生,Errors集合不會受到影響。所以,即使ADO命令成功執(zhí)行,這個集合中也可能含有錯誤信息。
· OLE DB提供者可能會將包含信息的消息或警告裝入Errors集合,錯誤號為0。所以不能只檢查集合中的錯誤號而假定錯誤已經(jīng)發(fā)生。比如,使用ODBC提供者與SQL Server連接,可能會得到一個“錯誤”,告知缺省的數(shù)據(jù)庫已經(jīng)改變了。
如果回頭看一下本章開始講到的對象模型,可能會發(fā)現(xiàn)Errors集合只能由Connection對象訪問。讀者可能會覺得奇怪,如果不顯式地創(chuàng)建一個Connection對象,如何訪問Errors集合?Recordset對象有一個ActiveConnection屬性,含有當(dāng)前記錄集的Connection對象,這意味著可以這樣得到Errors集合:
rsAuthors.ActiveConnection.Errors
如果想看發(fā)生的全部錯誤,則需要遍歷整個Errors集合:
For Each errAuthors In rsAuthors.ActiveConnection.Errors
' Display error
Next
為了顯示一些合理的錯誤信息,需要確切知道在Errors集合中到底有些什么。
Error對象包含表8-5所示的屬性:
表8-5 Error對象的屬性及說明
屬 性
說 明
Number
ADO錯誤號
NativeError
從數(shù)據(jù)提供者獲得的錯誤號
SQLState
連接到SQL數(shù)據(jù)庫時,5位的SQL狀態(tài)代碼
Source
引起錯誤的對象
Description
錯誤說明文本
這意味著循環(huán)過程現(xiàn)在可以變成這樣:
For Each errAuthors In rsAuthors.ActiveConnection.Errors
Response.Write "Number: " & errAuthors.Number & _
"<BR>NativeError: " & errAuthors.NativeError & _
"<BR>SQLState: " & errAuthors.SQLState & _
"<BR>Source: " & errAuthors.Source & _
"<BR>Description: " & errAuthors.Description & _
"<P>"
Next
8.5.2 ASP頁面中的ADO錯誤
在第4、7章,我們研究了ASP的錯誤,以及如何簡潔并徹底地處理這些錯誤。ASP 3.0的一個新特征就是自定義錯誤頁面,但這對于ADO確實用處不大,因為腳本中的變量無法傳入自定義的錯誤頁面。這就意味著我們無法檢測Errors集合。
面對這樣的情況,必須提供自己的錯誤處理。如果你使用JScript作為服務(wù)器端編程語言,那么你將擁有新的try/catch特性,但是VBScript對于錯誤的處理仍然有許多不足。目前,最好的檢測錯誤的方法是使用On Error Resume Next語句,然后在可能會引起錯誤的每一行ADO代碼后檢查Errors集合。就像這樣:
<%
On Error Resume Next
Dim rsAuthors
Dim strSQL
Set rsAuthors = Server.CreateObject("ADODB.Recordset")
strSQL = "SELECT MissingColumn1, MissingColumn2, au_lname, au_fname " & _
"FROM authors"
rsAuthors.Open strSQL, strConn, adOpenDynamic, adLockOptimistic, adCmdText
If CheckForErrors (rsAuthors.ActiveConnection) = False Then
While Not rsAuthors.EOF
Response.Write rsAuthors("au_lname") & ", " & _
rsAuthors("au_fname") & "<BR>"
rsAuthors.MoveNext
Wend
End If
rsAuthors.Close
Set rsAuthors = Nothing
%>
這里可使用CheckForErrors子程序來檢測是否有錯誤發(fā)生:
Function CheckForErrors(objConn)
Dim objError ' Error object
' Errors means the count will be greater than 0
If objConn.Errors.Count > 0 Then
' Loop through the errors
For each objError in objConn.Errors
' Eorros with number 0 are informational
If objError.number <> 0 then
Response.Write "<TABLE BORDER=1>" & _
"<TR><TD>Error Property</TD><TD>Contents</TD>" & _
"</TR><TR><TD>Number</TD><TD>" & objError.Number & _
"</TD></TR><TR><TD>NativeError</TD><TD>" & _
objError.NativeError & "</TD></TR>" & _
"<TR><TD>SQLState</TD><TD>" & objError.SQLState & _
"</TD></TR><TR><TD>Source</TD><TD>" & _
objError.Source & "</TD></TR>" & _
"<TR><TD>Description</TD><TD>" & _
objError.Description & "</TD></TR></TABLE><P>"
CheckForErrors = True
End If
Next
Else
CheckForErrors = False
End If
End Function
%>
這個程序檢測是否有錯誤,如果有,則為每一個錯誤創(chuàng)建一個表格,并給出了如圖8-11所示的結(jié)果。
圖8-11 顯示的錯誤結(jié)果
這并不是一個技術(shù)含量較高的解決方案,但確實是用VBScript所能做到的最好的解決方案。真正的不足是必須自己檢測錯誤。
8.6 小結(jié)
現(xiàn)在,應(yīng)該擴展基礎(chǔ)知識,研究Command對象,理解如何使用一些高級特性去改進性能和維護ASP頁面。
第9章 連接、命令和過程
上一章討論了ADO的基礎(chǔ)知識,內(nèi)容主要涉及Recordset對象以及對數(shù)據(jù)的處理。在大多數(shù)例子中,只是通過指定數(shù)據(jù)庫的表名來獲取數(shù)據(jù),但正如從對象模型中看到的,ADO還有其他允許訪問數(shù)據(jù)的對象。
本章將要更詳細地介紹這些對象,特別將研究以下內(nèi)容:
· Connection對象,以及如何用它來獲取數(shù)據(jù)和運行命令。
· Command對象,為什么需要該對象及其所具有的功能。
· 如何運行存儲過程,特別是那些需要參數(shù)的存儲過程。
· 一些簡單的改善ADO性能的優(yōu)化技巧。
· 數(shù)據(jù)整形的概念及如何使用。
如同介紹Recordset對象那樣,我們不打算覆蓋所涉及對象的全部方法和屬性。在這里只探討其中最重要的主題,以及那些適用于ASP開發(fā)人員的方法與屬性。
9.1 Connection對象
前一章中已經(jīng)提及,Connection對象是為我們與數(shù)據(jù)存儲提供連接的對象,但這并非Connection對象的全部功能。除了存儲連接的細節(jié)外(比如數(shù)據(jù)存儲的類型,以及其支持的特性),也可以利用Connection對象運行命令。
這些命令可能是查詢動作,比如更新、插入或刪除操作,也可以是返回一個記錄集的命令。讀者可能會覺得奇怪:既然有了Recordset對象,這又有什么用?這正是ADO的靈活性所在,可以根據(jù)當(dāng)前的情況,以及對當(dāng)前任務(wù)的適用性選擇使用任一種對象。
從Connection對象運行的命令一般是查詢動作,但了解能夠得到返回的記錄集也是非常有用的。
9.1.1 返回一個記錄集
為了從Connection對象返回一個記錄集,要使用Execute方法。語法是:
Connection.Execute CommandText, [RecordsAffected], [Options]
參數(shù)及說明如表9-1所示:
表9-1 Connection對象的Execute方法的參數(shù)及說明
參 數(shù)
說 明
CommandText
執(zhí)行的命令文本。與Recordset的Open方法中的Source參數(shù)相同,也能代表一個現(xiàn)有的Command對象
RecordsAffected
受命令執(zhí)行影響的記錄數(shù)
Options
命令選項,可以是一個或多個CommandTypeEnum或ExecuteOptionEnum常數(shù),詳細的值請見上一章
Execute方法可選擇地返回一個記錄集,在這種情況下只要將返回值賦給記錄集變量。例如:
Set conPubs = Server.CreateObject("ADODB.Connection")
conPubs.Open strConn
Set rsAuthors = conPubs.Execute("Authors")
讀者可能會奇怪使用Connection對象的Execute方法與使用Recordset對象的Open方法之間到底有什么區(qū)別?看上去區(qū)別不是很大,使用Recordset對象的Open方法可以改變光標(biāo)類型和鎖定類型。這些選項對于Connection對象的Execute方法是不可用的,因此永遠只能得到一個只能前移的、只讀的記錄集。
9.1.2 操作命令
如果正在運行操作命令,比如一個SQL UPDATE語句,那么可以使用RecordAffected參數(shù)找出有多少條記錄受到該命令的影響。例如:
Dim strSQL As String
Dim lngRecs As Long
strSQL = "UPDATE Titles SET Price = Price * 1.10" & "WHERE Type='Business'"
conPubs.Execute strSQL, lngRecs, adCmdText
Response.Write lngRecs & " records were updated."
上述代碼將所有類型為Business的書的單價增加了10%。一旦Execute命令執(zhí)行完畢,受Update命令影響的記錄數(shù)就返回到變量lngRecs中,這就是RecordsAffected參數(shù)。
注意,已經(jīng)為命令指定了adCmdText選項,告訴ADO CommandText參數(shù)是一個文本命令。一般這不是嚴(yán)格必須的,其目的只是讓ADO預(yù)先知道執(zhí)行的命令屬于何種類型,這樣能夠提高性能。記住,這個值可以是一個或多個CommandTypeEnum值。
無記錄集返回
如果上面的例子不返回記錄集,那么在Execute語句中加入另一個選項也是較好的方法:
conPubs.Execute strSQL, lngRecs, adCmdText + adExecuteNoRecords
使用adExecuteNoRecords告訴ADO執(zhí)行的命令不返回任何記錄。所以,ADO不必費心去創(chuàng)建一個記錄集。如果省略了該選項,那么ADO將會創(chuàng)建一個空的記錄集,很明顯這浪費了時間,因此加上這個選項會加快語句的執(zhí)行。
9.2 Command對象
Command對象特定地為處理各種類型的命令而設(shè)計,特別是那些需要參數(shù)的命令。與Connection對象相似,Command對象可以運行返回記錄集和不返回記錄集兩種類型的命令。實際上,如果命令不含有參數(shù),那么它并不關(guān)心是使用Connection對象,還是Command對象,還是Recordset對象。
9.2.1 返回記錄集
對于一個返回記錄集的命令,可使用Execute方法。然而,與Connection對象不同,必須使用CommandText屬性,而不能在Execute方法中使用命令文本。
Set cmdAuthors = Server.CreateObject("ADODB.Command")
cmdAuthors.CommandText = "Authors"
Set rsAuthors = cmdAuthors.Execute
這是告訴Command對象去執(zhí)行一個簡單的、返回一個只讀記錄集的命令的最簡單方法。
Execute方法也有一些可選參數(shù),如表9-2所示:
表9-2 Command對象的Execute方法的參數(shù)及說明
參 數(shù)
說 明
RecordsAffected
受命令影響的記錄數(shù)
Parameters
參數(shù)值數(shù)值
Options
命令選項,與Recordset的Open方法中的Options選項相似
參數(shù)RecordsAffected與Options同前面解釋的一樣,另外也可以使用CommandType屬性設(shè)置命令類型:
Set cmdAuthors = Server.CreateObject("ADODB.Command")
cmdAuthors.CommandText = "Authors"
cmdAuthors.CommandType = adCmdTable
如果不設(shè)置其他參數(shù),也可以在Execute行上設(shè)置,必須為它們使用逗號:
Set rsAuthors = cmdAuthors.Execute(, , adCmdTable)
在本章后面處理存儲過程時,將會看到參數(shù)Parameters的用途。
改變光標(biāo)類型
值得注意是,使用Execute方法返回的記錄集具有缺省的光標(biāo)類型。這意味著這是只能前移的、只讀的記錄集。雖然使用Execute方法不能改變這種情況,但對這個問題有一個解決的方法。
如果需要使用一個命令,并且要求不同的光標(biāo)和鎖定類型,那么應(yīng)該使用Recordset的Open方法,此時Command對象作為Recordset的數(shù)據(jù)源。例如:
cmdAuthors.ActiveConnection = strConn
cmdAuthors.CommandText = "Authors"
cmdAuthors.CommandType = adCmdTable
rsAuthors.Open cmdAuthors, , adOpenDynamic, adLockOptimistic
注意,在Open命令行中忽略了連接細節(jié),因為連接設(shè)置在Command對象中。連接細節(jié)在命令打開前已經(jīng)設(shè)置在Command對象的ActiveConnection屬性中。
9.2.2 操作命令
對于操作命令,比如那些無記錄返回的更新命令,整個過程相似,只需移去設(shè)置記錄集的代碼:
Set cmdUpdate = Server.CreateObject("ADODB.Command")
strSQL = "UPDATE Titles SET Price = Price * 1.10" & "WHERE Type='Business'"
cmdUpdate.ActiveConnection = strConn
cmdUpdate.CommandText = sSQL
cmdUpdate.CommandType = adCmdText
cmdUpdate.Execute , , adExecuteNoRecords
注意,我們在此設(shè)置了命令類型,然后在Execute行中增加了額外的設(shè)置選項。這段代碼運行UPDATE命令,并且保證不會創(chuàng)建新的記錄集。