標題:
[教學]
(實戰專題) 線上票選 下篇
[打印本頁]
作者:
小誌
時間:
2010-5-23 23:00
標題:
(實戰專題) 線上票選 下篇
防止重複投票的過濾機制
我們之前說過:在投票的程式網頁中按下『投下神聖的一票』按鈕後,投票的表單就會將投票資料送交votesave.asp程式進行處理,當自動轉向連結回到投票程式網頁畫面時,『你的一票選模範生』的字句變成『你已經投過票了!只能觀看投票結果!』,同時『投下神聖的一票』的按鈕也不再出現!這就是防止重複投票的過濾機制,在本例中我們利用session物件來建立過濾機制。
Session物件是ASP檔案共用的物件,每一位連線者都個別擁有屬於自己的Session物件,將資料寫入Session物件的方法如下:
Session("變數名稱")=變數值
複製代碼
當我們將資料寫入到Session物件中,只是將資料寫入到目前連線者的Session物件中,與其他的連線者並無關係,因此我們就可依照連線者目前Session物件的資料值來判斷連線者是否具有進行投票的權利。
[attach]814[/attach]
先進行變數名稱為checkvote的Session物件資料值,如果其資料值為"yes"代表投過票了,則將顯示於程式網頁中的訊息文字字串設定為『你已經投過票了!只能觀看投票結果!』,並且將決定顯示『投下神聖的一票』按鈕與否的確認變數『checkvote』設定為『no』代表不顯示投票按鈕。
如果Session物件其資料值為"no"則代表尚未投票,將顯示於程式網頁中的訊息文字字串設定為『你的一票選模範生』,並且將顯示投票按鈕的確認變數『checkvote』設定為『yes』代表顯示投票按鈕。
[attach]815[/attach]
Vote.asp
<%
'建立資料庫連結物件
Set conobject = Server.CreateObject("ADODB.Connection")
DBPath = Server.MapPath("vote.mdb")
'連結資料庫
conobject.Open "Driver={Microsoft Access Driver (*.mdb)};DBQ="&DBPath
'建立資料庫存取物件
Set RS=Server.CreateObject("ADODB.Recordset")
'打開資料表
RS.Open "Select * from student",conobject,0,1
'計算總投票數與設定得票率圖表寬度
VotePeople=RS("康小明")+RS("楊小誌")+RS("王小菲")+RS("梁詠琦")
IF RS("康小明")>0 then linelong1= 500*RS("康小明")/VotePeople
IF RS("楊小誌")>0 then linelong2= 500*RS("楊小誌")/VotePeople
IF RS("王小菲")>0 then linelong3= 500*RS("王小菲")/VotePeople
IF RS("梁詠琦")>0 then linelong4= 500*RS("梁詠琦")/VotePeople
'投票檢查
IF session("checkvote")="yes" then
msg="你已經投過票了!只能觀看投票結果!"
VoteButton="no"
Else
session("checkvote")="yes"
msg="你的一票選模範生"
VoteButton="yes"
End IF
%>
<CENTER>
<P><img border="0" src="logo.gif"><br>
<font color="#0000FF"><%=msg%></font></P>
<form method="POST" action="votesave.asp">
<table border="1">
<tr>
<td bgcolor="#FF3399"><font color="#FFFFFF">圈票處</font></td>
<td bgcolor="#FF3399"><font color="#FFFFFF">候選人</font></td>
<td bgcolor="#FF3399"><font color="#FFFFFF">得票數</font></td>
</tr>
<tr>
<td align="center">
<input type="radio" name="vote" value="康小明"></td>
<td>康小明</td>
<td><img border="0" src="vote.gif" Height="5" Width=<%=linelong1%>>
<%=RS("康小明")%>票</td>
</tr>
<tr>
<td align="center">
<input type="radio" name="vote" value="楊小誌"></td>
<td>楊小誌</td>
<td><img border="0" src="vote.gif" Height="5" Width=<%=linelong2%>>
<%=RS("楊小誌")%>票</td>
</tr>
<tr>
<td align="center">
<input type="radio" name="vote" value="王小菲"></td>
<td>王小菲</td>
<td><img border="0" src="vote.gif" Height="5" Width=<%=linelong3%>>
<%=RS("王小菲")%>票</td>
</tr>
<tr>
<td align="center">
<input type="radio" name="vote" value="梁詠琦"></td>
<td>梁詠琦</td>
<td><img border="0" src="vote.gif" Height="5" Width=<%=linelong4%>>
<%=RS("梁詠琦")%>票</td>
</tr>
</table>
<%IF VoteButton="yes" then %>
<p><input type="submit" value="投下神聖的一票"></p>
<%End IF%>
</form>
</CENTER>
複製代碼
作者:
小誌
時間:
2010-5-23 23:05
投票結果儲存程式
同樣的,我們先來看一下如何建立票選資料庫的連結與資料表的開啟,如下圖:
[attach]816[/attach]
發現跟我們投票程式網頁中,建立票選資料庫的連結與資料表開啟的程式敘述有何不同之處了嗎?沒錯,就是資料錄物件Open方法的第三與第四個參數設定不一樣!
在第三個指定資料物Recordset開啟類型的參數,我們變更指定類型值為1(可讀寫模式且資料錄可自由移動);第四個指定鎖定類型的參數,我們變更指定類型值為3,樂觀鎖定,因為筆者個人認為不可能有兩位連線者同時執行程式而進行同一筆資料錄更新作業,因此只在Update方法被呼叫時才將資料錄鎖定,資料錄一寫入資料庫後立即解除鎖定
如果我們將第四個指定鎖定類型的參數,依然指定類型值為1,則程式將會出現下圖的錯誤:
[attach]817[/attach]
為什麼會出現錯誤呢?因為若指定鎖定類型的參數類型值為1,則我們將無法使用Recordset物件的AddNew、Delete與Update方法,但是我們要更新投票票數就得用到Recordset物件的Update方法啊,所以參數類型值為1不能用,那我們可不可以指定參數類型值為2?當然可以,只是筆者個人偏好喜歡指定參數類型值為3(因為筆者天性樂觀?),那可不可以指定參數類型值為4?我們更新的資料只有一欄還不至於要進行批次鎖定啦!
投票結果儲存程式『votesave.asp』,在本程式中完全沒有網頁資料的顯示,本程式只負責將投票程式網頁中,所傳送過來的投票資料更新到資料庫中,然後將連結轉向回投票程式網頁。
更新投票結果
[attach]818[/attach]
先接收來自投票程式網頁中表單所傳送過來的投票資料,這個資料值其實就是表單中選擇鈕的Value屬性值(上圖綠色部分程式敘述)。
利用多執行路徑的 Select Case 敘述來決定哪位候選人的票數加1(上圖藍色部分程式敘述)。
利用Update方法將新的投票結果更新寫入到資料庫中(上圖紅色部分程式敘述)。
請注意:
當我們利用RS("欄位名稱")="更新後資料"的敘述將資料寫入資料錄欄位,這樣的敘述只是將資料寫到buffer(緩衝區)中,並沒有將更新的資料真正的寫入到資料庫中,只有當我們呼叫Recordset物件的Update方法時,更新後的資料才會真正的寫入資料庫。
最後,不要忘了加上 Response.Redirect "vote.asp" 這行程式敘述,轉向連結回投票程式網頁vote.asp去顯示最新的投票結果。
Votesave.asp
<%
'建立資料庫連結物件
Set conobject = Server.CreateObject("ADODB.Connection")
DBPath = Server.MapPath("vote.mdb")
'連結資料庫
conobject.Open "Driver={Microsoft Access Driver (*.mdb)};DBQ="&DBPath
'建立資料庫存取物件
Set RS=Server.CreateObject("ADODB.Recordset")
'打開資料表
RS.Open "Select * from student",conobject,1,3
'更新投票結果
vote=Request("vote")
Select case vote
case "康小明"
RS("康小明")=RS("康小明")+1
case "楊小誌"
RS("楊小誌")=RS("楊小誌")+1
case "王小菲"
RS("王小菲")=RS("王小菲")+1
case "梁詠琦"
RS("梁詠琦")=RS("梁詠琦")+1
End Select
RS.UPdate
Response.Redirect "vote.asp"
%>
複製代碼
作者:
小誌
時間:
2010-5-23 23:09
程式利用說明
當您直接使用本範例程式進行應用時,請自行修改資料庫中的欄位名稱,欄位要增加或減少,由您自行決定(相對的,各程式中的程式敘述也要增加),更改欄位名稱後,請記得修改程式網頁vote.asp及更新票選結果程式votesave.asp中的欄位名稱設定,例如:您將欄位名稱"康小明"更改為"劉得華",則程式網頁vote.asp及更新票選結果程式votesave.asp中的RS("康小明")同樣必須更改為RS("劉得華");票數長條圖圖形若您不喜歡,也可使用相關編輯軟體自行設計。
(實戰專題) 線上票選_完整程式碼壓縮檔下載:
[attach]819[/attach]
歡迎光臨 麻辣家族討論版版 (http://forum.twbts.com/)