ASP講座之七:ASP與資料庫(二)
作者:Eve Cole
更新時間:2009-05-30 19:55:02
在上一講中,我們學習如何與資料庫建立連接和從資料庫中檢索數據,今天的內容是如何在資料庫中新增資料、修改和刪除資料庫中的資料。
一、 在資料庫中新增資料方法一:使用SQL語句,範例wuf50.asp。
為了簡化以後的程序,將與Access資料庫的連接部分放在一個文件中,此文件以後需要用到時不再說明。
<% 'AdoAccess.asp
Option Explicit
Response.Expires = 0
'第一部分: 建立連接
Dim Cnn, StrCnn
Set Cnn = Server.CreateObject("ADODB.Connection")
StrCnn = "Provider = Microsoft.Jet.OLEDB.4.0; Data Source = C:InetpubhomeaspNorthwind.mdb"
Cnn.Open StrCnn
%>
程式wuf50.asp
<% @LANGUAGE = VBScript %>
<!--#include file="AdoAccess.asp"-->
<% ' wuf50.asp
'第二部分: 使用Connection 物件的Execute 新增數據
Dim StrSQL, rsTest
StrSQL = "INSERT INTO 運貨商(公司名稱,電話) VALUES('wu''feng','0571-7227298')"
Cnn.Execute StrSQL
%>
<HTML>
<BODY>
<% '第三部分: 將得到的記錄集顯示到瀏覽器上
Set rsTest = Cnn.Execute("Select * From 運貨商")
Do While Not rsTest.EOF
Response.Write rsTest(0) & " " & rsTest(1) & " " & rsTest(2) & " " & "<BR>"
rsTest.MoveNext
Loop
'第四部: 打掃戰場
Cnn.close
Set rsTest = Nothing: Set Cnn = Nothing
%>
</BODY>
</HTML>
請注意以下幾點:
1. 使用SQL語句在Access資料庫中新增資料時必須使用Insert Into,而向SQL Server資料庫新增數據,使用Insert就可以了。
2. 使用SQL語句加入資料的格式如上例,注意需要加入'wu'feng',在語句中必須使用'wu''feng',因為SQL語句使用'作為字串的分界符。
3. 把本例同以前所學的知識結合起來,就可以實現從HTML表單中加入資料。
4. 注意有一個資料類型為自動編號的字段,如本例中的“運貨商ID”,因此你大可不必考慮如何寫代碼獲得一個遞增的編號。
方法二:使用Recordset物件的Addnew方法,範例wuf51.asp。
<% @LANGUAGE = VBScript %>
<!--#include file="AdoAccess.asp"-->
<!--#include file="adovbs.inc"-->
<% ' wuf51.asp
'第二部分: 使用Recordset 物件的AddNew 方法新增數據
Dim StrSQL, rsTest
Set rsTest = server.CreateObject("ADODB.Recordset")
rsTest.CursorType = adOpenKeySet 'adOpenDynamic
'沒有下面這一句, 將不允許更新資料庫, 為什麼?
rsTest.LockType = adLockOptimistic
rsTest.Open "運貨商",Cnn,,,adCmdTable
rsTest.AddNew
rsTest("公司名稱") = "wu'feng"
rsTest("電話") = "0571-7227298"
rsTest.Update
%>
<HTML>
<BODY>
<% '第三部分: 將得到的記錄集顯示到瀏覽器上
'將資料庫指標移到表中的第一筆記錄
If Not rsTest.EOF <> 0 Then
Response.Write "表格中現有[" & rsTest.RecordCount & "] 條資料" & "<Br><Br>"
rsTest.MoveFirst
End If
Do While Not rsTest.EOF
Response.Write rsTest(0) & " " & rsTest(1) & " " & rsTest(2) & " " & "<BR>"
rsTest.MoveNext
Loop
'第四部: 打掃戰場
Cnn.close
Set rsTest = Nothing: Set Cnn = Nothing
%>
</BODY>
</HTML>
分析:
1. 為何要設定rsTest.LockType = adLockOptimistic
Recordset物件的LockType屬性有四個可選值:
adLockReadOnly-預設值,表示以唯讀方式開啟記錄集,因而無法無法變更數據,在這種情況下使用AddNew方法就會發生錯誤。
adLockPessimistic-保守式記錄鎖定(逐一)。採用編輯時立即鎖定資料來源的記錄的方式。此時,其他用戶不能存取該資料。
adLockOptimistic ——開放式記錄鎖定(逐一)。只在呼叫Update 方法時鎖定記錄。想想,這個屬性是不是跟我們曾經說過的Application物件的Lock、Unlock屬性的意思差不多。
adLockBatchOptimistic-開放式批次更新。用於成批更新數據,與UpdateBatch方法相對應。
順便我們再提一下上一講中提到的CursorType 屬性,它同樣有四個值:
adOpenForwardOnly-僅向前遊標,預設值,只能在記錄中向前捲動。這可以節省資源並提高效能。
adOpenStatic-靜態遊標。可以用來尋找資料或產生報表的記錄集合的靜態副本。另外,對其他使用者所做的新增、變更或刪除不可見。 推薦在ASP中只使用這兩種遊標。
adOpenKeyset——鍵集遊標。鍵集遊標與動態遊標相似,不同的只是禁止查看其他用戶添加的記錄,並禁止訪問其他用戶刪除的記錄,其他用戶所作的數據更改將依然可見。
adOpenDynamic——動態遊標。可以看見其他使用者所做的新增、變更和刪除。允許在記錄集中進行所有類型的移動。
可以肯定的一定是,這樣抽象的描述有點似是而非,還是不太明白,簡單的說,
(1) 如果僅僅檢索數據,使用預設值就可以了;
(2) 如果使用Update方法更新一條數據,LockType屬性使用adLockOptimistic,使用UpdataBatch方法成批更新數據,則使用adLockBatchOptimistic。
(3) 如果對資料庫有寫動作,CursorType 屬性一般使用adOpenKeyset就夠了。
怎麼樣?即使還不太明白,但會用了吧。
2. 如果你不精通資料庫,通常在輸出顯示前使用rsTest.MoveFirst將指標移至第一筆記錄是大有益處的。但如果資料庫中沒有任何數據,就無法使用MoveFirst方法,所以使用前先用rsTest.EOF屬性判斷資料庫中是否有數據。
3. 只有當遊標類型設為adOpenKeyset或adOpenStatic時,才能使用RecordCount屬性(取得記錄集中的記錄數目)。
二、 修改資料庫中已存在的資料方法一:使用SQL 語句。例wuf52.asp,程式基本上與wuf50.asp類似,這裡僅列出關鍵部分。
'第二部分: 使用Connection 物件的Execute 方法修改數據
Dim StrSQL, rsTest
StrSQL = "UPDATE 運貨商SET 電話= '(503) 555-3188' WHERE 電話LIKE '%99%'"
Cnn.Execute StrSQL
修改資料不用INSERT INTO…VALUES,而是用UPDATE…SET語句,WHERE子句的意思是將含有字串「99」(「LIKE」、「%」在模糊查詢時常用到)的電話號碼改為(503) 555-3188,如果不設定條件,表中所有的電話號碼都會被改掉。
方法二:使用Recordset 物件的Update 方法。程式wuf53.asp(類似例程wuf51.asp)
'第二部分: 使用Recordset 物件的Update 方法修改數據
Dim StrSQL, rsTest
Set rsTest = server.CreateObject("ADODB.Recordset")
rsTest.LockType = adLockOptimistic
StrSQL = "SELECT 姓氏,名字,出生日期FROM 僱員WHERE 出生日期= #55-03-04#"
rsTest.Open StrSQL, Cnn,,,adCmdText
rsTest("名字") = "中文"
rsTest.Update
分析:
1. SQL語句中,如果資料庫是Access資料庫,日期用#55-03-04#括起來,如本例;如果是SQL Server資料庫,日期要用'55-03-04'括起來。
2. rsTest.Open StrSQL, Cnn,,,adCmdText中,由於第一個參數是SQL語句,所以第五個參數為adCmdText,其實,第五個參數完全可以省略,但加上它會使腳本的執行效率更高。
3. 使用方法一,一次可以更新符合條件的所有記錄(多筆記錄或一筆記錄),但方法二中的Update只能修改目前記錄(符合條件的第一筆記錄)。
三、 刪除資料庫中的資料方法一:使用SQL 語句。例程wuf55.asp
'第二部分: 使用SQL 語句刪除數據
Dim StrSQL, rsTest
StrSQL = "DELETE FROM 運貨商WHERE 電話= '0571-7227298'"
Cnn.Execute StrSQL
方法二:使用Recordset 物件的Delete 方法。例行wuf56.asp
'第二部分: 使用Recordset 物件的Delete 方法刪除數據
Dim StrSQL, rsTest
Set rsTest = server.CreateObject("ADODB.Recordset")
rsTest.LockType = adLockOptimistic
StrSQL = "SELECT * FROM 運貨商WHERE 電話= '0571-7227298'"
rsTest.Open StrSQL, Cnn,,,adCmdText
While Not rsTest.EOF
rsTest.Delete
rsTest.MoveNext
Wend
若記錄集中有多筆記錄符合條件,則必須使用循環,否則,Delete方法只刪除目前記錄,即第一筆符合條件的記錄。
四、 其它一些有用的知識
1. 成批更新數據上面我們講瞭如何使用Recordset物件的Update方法更新數據,事實上,Recordset 物件可支援兩類更新:立即更新和批次更新。
使用立即更新,一旦呼叫Update 方法,對資料的所有變更將立即寫入現行資料來源。
使用批次更新,可以使提供者將多個記錄的變更存入緩存,然後使用UpdateBatch 方法在單一呼叫中將它們傳送給資料庫。更新多個記錄時,批次更新比立即更新更有效。
缺省為立即更新模式。使用批次更新模式,要使用客戶端遊標,例wuf54.asp。
<% @LANGUAGE = VBScript %>
<!--#include file="AdoAccess.asp"-->
<!--#include file="adovbs.inc"-->
<% ' wuf54.asp
'第二部分: 批次更新模式
Dim StrSQL, rsTest
Set rsTest = server.CreateObject("ADODB.Recordset")
rsTest.CursorLocation = adUseClient '使用客戶端遊標類型
rsTest.LockType = adLockBatchOptimistic
StrSQL = "SELECT * FROM 運貨商WHERE 電話LIKE '%99%'"
rsTest.Open StrSQL, Cnn,,,adCmdText
rsTest.MoveFirst
While Not rsTest.EOF
rsTest("公司名稱") = "中文"
rsTest.MoveNext
Wend
rsTest.UpdateBatch
%>
<HTML>
<BODY>
<% '第三部分: 將得到的記錄集顯示到瀏覽器上
rsTest.Requery
Do While Not rsTest.EOF
Response.Write rsTest(0) & " " & rsTest(1) & " " & rsTest(2) & " " & "<BR>"
rsTest.MoveNext
Loop
'第四部: 打掃戰場
Cnn.close
Set rsTest = Nothing: Set Cnn = Nothing
%>
</BODY>
</HTML>
注意:
1) rsTest.CursorLocation = adUseClient有兩個值,另一個值為adUseServer(預設),對初學者而言,Recordset物件的遊標類型是比較難的部分,這裡不再詳細介紹,以免越來越糊塗,請在實際處理中慢慢摸索(多試)。
2) rsTest.Requery:使用Requery 方法刷新資料來源的Recordset 物件的全部內容。呼叫該方法等於相繼呼叫Close 和Open 方法。
2.學會使用Recordset物件的Filter 屬性
<% @LANGUAGE = VBScript %>
<!--#include file="AdoAccess.asp"-->
<!--#include file="adovbs.inc"-->
<% ' wuf57.asp
'第二部分: 使用Recordset 物件的Filter 屬性
Dim StrSQL, rsTest
Set rsTest = server.CreateObject("ADODB.Recordset")
rsTest.CursorType = adOpenStatic
rsTest.LockType = adLockOptimistic
rsTest.Open "運貨商",Cnn,,,adCmdTable
'篩選出符合條件的記錄,而其它記錄則被過濾掉
rsTest.Filter = "公司名稱= 'wu''feng'"
If rsTest.EOF Then '若無此記錄,則新增
rsTest.AddNew
rsTest("公司名稱") = "wu'feng"
rsTest("電話") = "0571-7227298"
rsTest.Update
Else '若有符合條件的記錄,修改符合條件的第一筆記錄
rsTest("電話") = "(571) 7227298"
rsTest.Update
End If
%>
<HTML>
<BODY>
<% '第三部分: 將得到的記錄集顯示到瀏覽器上
'請仔細比較下面這句話要與不要的差別
'rsTest.Filter="" '用來清除Filter 屬性
rsTest.MoveFirst
Do While Not rsTest.EOF
Response.Write rsTest(0) & " " & rsTest(1) & " " & rsTest(2) & " " & "<BR>"
rsTest.MoveNext
Loop
'第四部: 打掃戰場
Cnn.close
Set rsTest = Nothing: Set Cnn = Nothing
%>
</BODY>
</HTML>
3.除了上面介紹的兩種方法之外,還可使用SQL語句、Command物件的Excute方法來維護資料庫。範例wuf58.asp
<% @LANGUAGE = VBScript %>
<!--#include file="AdoAccess.asp"-->
<!--#include file="adovbs.inc"-->
<% ' wuf58.asp
'第二部分: 使用SQL語句、Command物件的Excute方法維護資料庫
Dim StrSQL, rsTest, cmdChange
StrSQL = "INSERT INTO 運貨商(公司名稱,電話) VALUES('wu''feng','0571-7227298')"
' 建立命令物件。
Set cmdChange =server.CreateObject("ADODB.Command")
Set cmdChange.ActiveConnection = Cnn
cmdChange.CommandText = StrSQL
cmdChange.Execute
%>
<HTML>
<BODY>
<% '第三部分: 將得到的記錄集顯示到瀏覽器上
Set rsTest = server.CreateObject("ADODB.Recordset")
rsTest.Open "運貨商", Cnn, , , adCmdTable
Do While Not rsTest.EOF
Response.Write rsTest(0) & " " & rsTest(1) & " " & rsTest(2) & " " & "<BR>"
rsTest.MoveNext
Loop
'第四部: 打掃戰場
Cnn.close
Set rsTest = Nothing: Set Cnn = Nothing
%>
</BODY>
</HTML>
本講主要介紹了維護資料的三種方法,初學者只要掌握前兩種方法就可以了。一般而言,盡量使用SQL語句解決問題,簡單明了;而使用Recordset物件的最大好處是可以利用其大量的屬性和豐富的遊標類型,有更多的選擇,但也為使用帶來一些難題,關鍵在於多摸索,多試驗。