苏驰
前言:很多网页设计者可能都面临过这样一个问题:设计一个表单让使用者输入之后,将使用者所输入的内容建立到数据库中,可是一但使用者输入的内容有不合型态(数字字段却输入文字)的情况或者使用者所输入的内容不符合系统管理者的要求时,却无法提醒使用者哪里出错以便让使用者重新填写表单,一般人或许会使用浏览器的后退按钮回到表单页然后将填错的资料重填,但是如果加入数据库的程序与表单内容放在同一个程序之内的话,那使用者就没有机会回上一页重填资料了。大多数人通常是用Session解决这个问题,但这又就带来了一个问题:Session占系统资源很大!解决上述问题有两种方法:一种是通过JavaScript使用前端控制,另一种是通过ASP子程序来作服务器端控制。下面我就是介绍的如何使用通过ASP子程序来作服务器端控制来完成。在数据库的使用上也跟以往不同,我这一次使用的是SQL 7.0为大家作介绍,下面程序所连结的数据库是SQL 7.0中所内建的Pubs数据库,使用者不必重新建立,只要将预存程序建立在Pubs数据库上即可。
附注:下面的程序是我在为一个超市设计网页时编写的,由于这里主要是介绍编写技巧,所以我不再进行编整,不过读者可以根据需要对里面的内容进行修改。
BookStore.asp
<%@ TRANSACTION=Required LANGUAGE="VBScript"%>
<%Response.Buffer=True%>
<!-- #include file=adovbs.inc -->
<%
注解:建立数据库连结:
SET Conn = Server.CreateObject("ADODB.Connection")
注解:利用数据库连结的ConnectionString属性指定欲连结的数据库信息,在这里我们将数据库驱动程序设为SQL Server,数据库服务器名称为Jackal,数据库为Pubs数据库:
Conn.ConnectionString = "driver={SQL Server}" & _
";SERVER=Jackal;UID=sa;PWD=;DATABASE=pubs"
注解:以open方法开启数据库:
Conn.Open
注解:建立Command对象;以ActiveConnection属性来连结数据库连结对象Conn:
Set Cmd = Server.CreateObject("ADODB.Command")
Cmd.ActiveConnection = Conn
注解:建立资料集合对象;SET rsForm = Server.CreateObject("ADODB.RecordSet"),定义strFeedBack, strTitle字符串变量,分别代表表单错误信息和数据库错误信息:
DIM strFeedBack, strTitle
注解:定义表单变量:
DIM stor_id, stor_name, stor_address, city, state, zip
%>
<html>
<head>
<script RUNAT="Server" LANGUAGE="VBScript">
下面就要编写RetrieveForm子程序了,其作用是接收由表单所提供的资料:
SUB RetrieveForm(stor_id)
注解:搭配 Cmd.ActiveConnection = Conn使用,并将commamndtype属性设定为 adCmdStoredProc,表示commandtext为预存程序:
Cmd.CommandType = adCmdStoredProc
Cmd.CommandText = "proc_retrieve_store"
注解:以Parameters.Append的方法加入一个参数"stor_id"以作为预存程序的输入参数之用:
Cmd.Parameters.Append cmd.CreateParameter("stor_id",adChar, adParamInput,4,stor_id)
注解:执行预存程序:
SET rsForm = Cmd.Execute
注解:删除stor_id参数:
Cmd.Parameters.Delete(0)
END SUB
完成上一步骤,下一步就是编写SetFromForm子程序,其作用是将使用者之前所输入的表单值回写至表单:
SUB SetFromForm
注解:取出表单中各字段值并传给指定变量:
stor_id = Request.Form("stor_id")
stor_name = Request.Form("stor_name")
stor_address = Request.Form("stor_address")
city = Request.Form("city")
state = Request.Form("state")
zip = Request.Form("zip")
END SUB
(注解:从资料集合对象中将值取出并显示在表单中, strName 代表表单名称, intSize代表表单大小, intMax代表表单所允许输入最大字段长度, Server.HTMLEncode(strValue) 代表表单内容。)
Sub ShowText(strName, strValue, intSize, intMax)
Response.Write "<INPUT TYPE=Text NAME=" & strName & _
" ID=" & strName & _
" onFocus=select()" & _
" SIZE=" & intSize & _
" MAXLENGTH=" & intMax & _
" VALUE=" & chr(34) & Server.HTMLEncode(strValue) & chr(34) & ">"
End Sub
下面是EditForm子程序,其作用是更新数据区段:
Function EditForm()
注解:定义错误信息字符串变量:
DIM strErr
strErr = ""
IF NOT Len(Request("stor_id")) > 0 THEN
strErr = strErr & "请输入编号.<BR>"
END IF
IF NOT Len(Request("stor_name")) > 0 THEN
strErr = strErr & "请输入名称.<BR>"
END IF
IF NOT Len(Request("stor_address")) > 0 THEN
strErr = strErr & "请输入地址.<BR>"
END IF
IF NOT Len(Request("city")) > 0 THEN
strErr = strErr & "请输入城市名.<BR>"
END IF
IF NOT Len(Request("state")) > 0 THEN
strErr = strErr & "请输入省名.<BR>"
END IF
注解:将表单错误信息传回EditForm:
EditForm = strErr
End Function
下面是InsertForm子程序:
Function InsertForm()
DIM strSQL
strSQL = "proc_insert_store"
注解:以Command对象的CommandText 属性指定对数据库下达的命令是通过proc_insert_store这个预存程序来完成:
Cmd.CommandText = strSQL
注解:以Command对象的CommandType 属性决定对数据库请求的型态是为预存程序:
Cmd.CommandType = adCmdStoredProc
注解:呼叫SetParms子程序:
SetParms
注解:以Command对象的Execute方法执行预存程序:
Cmd.Execute
注解:将SetParms子程序中所附加的msg参数传回给strMsg错误信息字符串变量:
strMsg = cmd.Parameters("msg")
InsertForm = strMsg
End Function
接着是建立setparms子程序:
Sub SetParms()
注解:以Command的Append方法将Parameter对象加到Parameters对象集合中,作为预存程序的输入参数之用这是为了取得表单的内容值,只有在更新资料或加入资料时才必须呼叫这段子程序:
cmd.Parameters.Append cmd.CreateParameter("RETURN_VALUE", adInteger, adParamReturnValue)
cmd.Parameters.Append cmd.CreateParameter("id", adChar, adParamInput,4,stor_id)
cmd.Parameters.Append cmd.CreateParameter("stor_name", adVarChar,adParamInput,40,stor_name)
cmd.Parameters.Append cmd.CreateParameter("stor_address", adVarChar, adParamInput,40,stor_address)
cmd.Parameters.Append cmd.CreateParameter("city", adVarChar, adParamInput,20,city)
cmd.Parameters.Append cmd.CreateParameter("state", adChar, adParamInput,2,state)
cmd.Parameters.Append cmd.CreateParameter("zip", adChar, adParamInput,5,zip)
cmd.Parameters.Append cmd.CreateParameter("msg", adVarChar, adParamInput,60, " ")
End Sub
下面是UpdateForm子程序:
Function UpdateForm (intID)
注解:以Command对象的CommandText 属性指定对数据库下达的命令是通过proc_update_store这个预存程序来完成:
Cmd.CommandText = "proc_update_store"
注解:以Command对象的CommandType 属性决定对数据库请求的型态是为预存程序:Cmd.CommandType = adCmdStoredProc
SetParms
Cmd.Execute
注解:将 SetParms子程序中所附加的msg参数传回给 strMsg错误信息字符串变量:
strMsg = cmd.Parameters("msg")
End Function
下面是DeleteForm子程序:
Function DeleteForm (intID)
注解:以Command对象的CommandText 属性指定对数据库下达的命令是通过proc_delete_store这个预存程序来完成:
Cmd.CommandText = "proc_delete_store"
注解:以Command对象的CommandType 属性决定对数据库请求的型态是为预存程序:
Cmd.CommandType = adCmdStoredProc
注解:以Parameters.Append的方法加入一个参数"id"以作为预存程序的输入参数之用:
cmd.Parameters.Append cmd.CreateParameter("id", adChar, adParamInput,4,stor_id)
注解:以Parameters.Append的方法加入一个参数"msg"以作为预存程序的输出参数之用:
cmd.Parameters.Append cmd.CreateParameter("msg",adVarChar, adParamOutput,60,"")
Cmd.Execute
注解:将 SetParms子程序中所附加的msg参数传回给 strMsg错误信息字符串变量:
strMsg = cmd.Parameters("msg")
SET Cmd.ActiveConnection = Nothing
Set Cmd = Nothing
END FUNCTION
</script>
<meta http-equiv="Content-Type" content="text/html; charset=big5">
<title>设定新商店</title>
</head>
<body>
<%
(注解:决定表单内容,表单传送目的为同一个档案。)
%>
<form NAME="StoreForm" ACTION="<%=Request.ServerVariables("PATH_INFO")%>" METHOD="post" >
<%
注解:以表单按钮决定该执行更新加入或删除资料
SELECT CASE Request("Process")
CASE "加入资料"
DIM intNewID
注解:使用者填完表单先呼叫SetFromForm子程序取得表单内容先将表单错误信息传回:
SetFromForm
strStatus = EditForm
注解:如果没有发生表单错误就呼叫InsertForm子程序将资料写入数据库:
IF strStatus = "" THEN
注解:更新数据库设定,显示变量,重新显示表单输入值,并让使用者知道运作情形.
strStatus = InsertForm
intNewID = Cmd.Parameters("RETURN_VALUE")
IF Len(Trim(strStatus)) = 0 THEN
strFeedBack = "名称已建立至数据库.<BR>"
ELSE
strFeedBack = strStatus
END IF
ELSE
注解:设定显示变量,重新显示表单输入值,并让使用者知道运作情形.
strFeedBack = strStatus
END IF
strTitle = "新名称设定完成"
CASE "更新资料"
注解:使用者填完表单先呼叫 SetFromForm子程序取得表单内容先将表单错误信息传回:
SetFromForm
strStatus = EditForm
IF strStatus = "" THEN
strStatus = UpdateForm (stor_id)
IF Len(Trim(strStatus)) = 0 THEN
strFeedBack = "名称资料已经更新.<BR>"
ELSE
strFeedBack = strStatus
END IF
ELSE
strFeedBack = strStatus
END IF
strTitle = "名称资料更新完成"
CASE "删除资料"
注解:先呼叫SetFromForm子程序取得表单内容再将表单错误信息传回:
SetFromForm
注解:呼叫DeleteForm将子程序并将数据库中stor_id字段值等于表单名称为stor_id之值的资料删除并将数据库错误信息传回:
strStatus = DeleteForm (Request("stor_id"))
IF strStatus = "" THEN
注解:数据库运作无误:
strFeedback = "<B>名称资料已经删除.</B><BR>"
ELSE
注解:设定显示参数并重新显示表单内容让使用者了解问题所在
strFeedback = strStatus
END IF
strTitle = "名称删除完成"
CASE ELSE
strTitle = "名称维护与管理"
strFeedback = "不被认可的维护管理程序: <B>" & Request("Process") & "</B>.
<BR>"
END SELECT
注解:显示表单错误信息和数据库错误信息:
Response.Write "<H3>" & strTitle & "</H3><BR>"
Response.Write "<B>" & strFeedBack & "</B><BR>"
注解:如果管理程序不为删除程序则显示表单:
IF Request("Process") <> "删除资料" THEN
%>
<table border="0" width="100%">
<tr>
<td align="left">
编号:
</td>
<td align="left">
<%ShowText "stor_id", stor_id, 4, 4 %>
</td>
</tr>
<tr>
<td align="left">
名称:
</td>
<td align="left">
<%ShowText "stor_name", stor_name, 40, 40 %>
</td>
</tr>
<tr>
<td align="left">
通信地址:
</td>
<td align="left">
<%ShowText "stor_address", stor_address, 40, 40 %>
</td>
</tr>
<tr>
<td align="left">
城市:
</td>
<td align="left">
<%ShowText "city", city, 20, 20 %>
</td>
</tr>
<tr>
<td align="left">
省:
</td>
<td align="left">
<%ShowText "state", state, 2, 2%>
</td>
</tr>
<tr>
<td align="left">
邮政编码:
</td>
<td align="left">
<%ShowText "zip", zip, 5, 5 %>
</td>
</tr>
</table>
<table border="0" width="100%">
<tr>
<td><center>
<% IF IsNumeric(stor_id) AND stor_id > 0 THEN
注解:如果使用者已经将资料加入数据库就显示更新资料和删除资料的按钮
%>
<input type="submit" value="更新资料" name="Process">
<input type="submit" value="删除资料" name="Process" tabindex="36">
<% ELSE %>
<input type="submit" value="加入资料" name="Process" tabindex="36">
<% END IF %>
<input type="reset" value="清除资料" name="Reset" tabindex="37">
</center>
</td>
</tr>
</table>
<%
END IF
注解:释放数据库资源,如果数据库集合还处于连结状态则将数据库连结关闭:
IF rsForm.State = adStateOpen THEN
rsForm.Close
SET rsForm = Nothing
END IF
Conn.Close
Set Conn = Nothing
Set Cmd = Nothing
%>
</form>
</body>
</html>
小结:
经过上面几步,所有的部分就算是基本完成,大家可以拿来用了。其实上面的程序并不算太复杂,如果朋友你没有使用SQL 的经验,对一些SQL的ADO对象与属性和方法可能感觉很陌生,不过在稳定性和安全性以及扩充性来讲,SQL比Access 2000强大的太多了,如果你对Access 2000在Web Server上的应用已经有了一定的基础,我建议你学习SQL。希望这些对你有所帮助。
……