ASP访问数据库的三种方式 随着Internet/Intranet技术的飞速发展,Web成了新的商家必争之地,各家厂商都希望通过Internet/Intranet技术与最终用户建立直接的联系,比如在Web上向用户推销产品、方便用户在网上查询自己喜欢的商品并提供网上订购服务等。于是基于Web方式的数据库技术应运而生。但是在传统的HTML页面中,访问数据库一般是通过公用网关接口(CGI)来实现,这种方式不仅开发困难,而且在出现大量并发请求时会显著地降低服务器的运行效率,而采用ASP(Active Server Pages)技术实现数据库访问就能较好地解决这个问题。
微软的ASP技术是一种运行于服务器端的脚本编写模型,它使开发者可以使用几乎所有的脚本语言(VBScript、Jscript或Perl等)编写脚本,这些脚本可以执行应用程序逻辑,并能够调用ActiveX组件执行特殊任务,如数据库查询、文件输入输出等。它将IDC的简单性和ISAPI的灵活性综合在一起。自从Microsoft IIS 3.0(Internet Information Server 3.0)出现以来,微软提出并一直致力于发展ASP技术。至今,ASP技术得到了进一步的发展,在IIS 4.0中提供了ASP脚本调试工具、事务处理、新的ActiveX组件、RDS等新特性。
在ASP脚本中可以通过三种方式访问数据库:传统的IDC(Internet Database Connector)方式,ADO(ActiveX Data Objects)方式以及RDS(Remote Data Service)方式。从概念上来讲,这三种访问方式对数据库的访问是由Internet Information Server来完成的。如图1所示。 Web浏览器用HTTP协议向Internet信息服务器(IIS)递交请求。Internet信息服务器执行访问数据库的操作,并以一个HTML格式的文档作为回答。
一.Internet数据库接口(IDC)
IDC是一个传统的数据库查询工具,用来定义和执行数据库查询的SQL命令,并向浏览器返回一个指定数据格式的页面。使用IDC访问数据库最大的特点是简单,几乎不需要编程就能实现对数据库的访问。
IDC使用两种文件来控制如何访问数据库以及如何创建返回的Web页面。这些文件分别是IDC (.idc)文件和HTML扩展(.htx)文件。
.idc文件必须包括ODBC数据源(Datasource)、HTML扩展文件的文件名(Template)以及要执行的SQL语句(SQLStatement)。此外还有许多可选字段,可以根据需要选用。
.htx文件是带有用<%%>或<!--%%-->括起来的附加标记的 HTML 文档,IDC 用这些标记将动态数据添加到文档中。在.htx文件中有六个关键字(begindetail、enddetail、if、else、endif和"%z")用来控制数据库中的数据怎样和.htx文件中HTML格式进行合并。数据库列名说明HTML文档中什么数据被返回。
下面是IDC应用的简单示例,这个例子是一个虚拟水果店的库存量查询。
.idc文件: Datasource: Kucun
<!-- 指定预先建立的数据源Kucun -->
Template: IDCReslt.htx
<!-- 相应的.htx文件的文件名和路径 -->
SQLStatement: SELECT * FROM 库存表
<!-- 要执行的SQL查询命令 -->
.htx文件:<HTML><HEAD><TITLE>水果店库存量查询结果</TITLE></HEAD>
<BODY>
<TABLE BORDER=1><CAPTION>水果店库存量查询结果</CAPTION>
<%begindetail%>
<%if CurrentRecord EQ 0 %>
<!-- CurrentRecord表示当前返回的记录-->
<TR><TD>序号</TD><TD>商品名称</TD><TD>库存量</TD><TD>进价</TD><TD>单位</TD><TD>进货日期</TD></TR>
<%endif%>
<!-- 输出查询返回的列-->
<TR><TD><%ID%></TD><TD><%商品名称%></TD><TD><%库存量%></TD><TD><%进价%></TD><TD><%单位%></TD><TD><%进货日期%></TD></TR>
<%enddetail%>
</TABLE></BODY></HTML>
注意:<%begindetail%>和<%enddetail%>之间的部分划定了界线,决定数据库中的哪些行将作为返回数据并显示在文档中。查询返回的列被<%%>包围,就象例子中的<%商品名称%> 和<%库存量%>等。
要执行IDC查询,通常的做法是在HTML文件中嵌入一个.idc文件的连接。例如,下面的HTML语句向Web服务器发出了请求,要求执行idctest.idc文件。
<A HREF="http://LocalHost/idctest/idctest/idctest.idc">库存量查询</A>
当Web服务器接到这个请求后,就调用Httpodbc.dll(IDC),与一定的数据源相连并把SQL命令传给数据库。当SQL语句被执行后,IDC把返回的数据融入到.htx文件中。IDC再把这个文档返回给Web服务器,Web服务器再返回给浏览器。运行结果如图2所示。
二.ActiveX数据对象(ADO)
与IDC不同,用ADO访问数据库更类似于编写数据库应用程序,ADO把绝大部分的数据库操作封装在七个对象中,在ASP页面中编程调用这些对象执行相应的数据库操作。ADO是ASP技术的核心之一,它集中体现了ASP技术丰富而灵活的数据库访问功能。ADO建立了基于Web方式访问数据库的脚本编写模型,它不仅支持任何大型数据库的核心功能,而且支持许多数据库所专有的特性。ADO使用本机数据源,通过ODBC访问数据库。这些数据库可以是关系型数据库、文本型数据库、层次型数据库或者任何支持ODBC的数据库。ADO的主要优点是易用、高速、占用内存和磁盘空间少,所以非常适合于作为服务器端的数据库访问技术。相对于访问数据库的CGI程序而言,它是多线程的,在出现大量并发请求时,也同样可以保持服务器的运行效率,并且通过连接池(Connection Pool)技术以及对数据库连接资源的完全控制,提供与远程数据库的高效连接与访问,同时它还支持事务处理(Transaction),以开发高效率、高可靠性的数据库应用程序。
正是因为使用ADO需要编写脚本程序,所以ADO能够实现更复杂、更灵活的数据库访问逻辑。目前,ADO包括Command、Connection、Recordset等七个对象和一个动态的Properties集合,绝大部分的数据库访问任务都可以通过它们的组合来完成。
一般使用ADO访问数据库的ASP脚本程序应该使用Connection对象建立并管理与远程数据库的连接;使用Command对象提供灵活的查询;而使用Recordset对象访问数据库查询所返回的结果。这三者是ADO中最基本也最核心的对象。下面的例子解释了如何使用这三个对象访问数据库。
<% Dim strDSN, strSQL
'定义用到的变量
Dim cn, rs, cm , ObjName, ObjKucun, ObjPrice, ObjUnit, ObjDate
strDSN = "FILEDSN=Kucun.dsn"
'建立DSN字符串
Set cn = Server.CreateObject("ADODB.Connection")
'创建Connection对象的一个实例
cn.Open strDSN
'与strDSN指定的数据源建立连接
Set cm= Server.CreateObject("ADODB.Command")
'创建Command对象的一个实例
Set cm.ActiveConnection = cn
'指定cm使用cn所建立的数据库连接
cm.CommandText = "INSERT INTO 库存表(商品名称,库存量,进价,单位,进货日期) VALUES (?,?,?,?,?)"
'预定义带参数的SQL查询命令
cm.Prepared = True
'通知数据源预处理该查询命令
cm.Parameters.Append cm.CreateParameter("商品名称",200, ,255 )
'定义查询参数
cm.Parameters.Append cm.CreateParameter("库存量",200, ,255 )
cm.Parameters.Append cm.CreateParameter("进价",200, ,255 )
cm.Parameters.Append cm.CreateParameter("单位",200, ,255 )
cm.Parameters.Append cm.CreateParameter("进货日期",200, ,255 )
cm("商品名称") = "葡萄"
'给参数赋值
cm("库存量") = 400
cm("进价") = 0.8
cm("单位") = "斤"
cm("进货日期") = #95-6-12#
cm.Execute
'按照给定的参数值执行预定义的SQL查询命令
cm("商品名称") = "柿子"
cm("库存量") = 300
cm("进价") = 0.4
cm("单位") = "斤"
cm("进货日期") = #95-6-11#
cm.Execute
Set rs= Server.CreateObject("ADODB.Recordset")
'创建Recordset对象的一个实例
strSQL = "SELECT * FROM 库存表"
'建立查询命令字符串
rs.Open strSQL, cn
'使用cn的数据库连接执行strSQL定义的查询命令
Set objName = rs("商品名称")
'将返回的列保存在变量中
Set objKucun = rs("库存量")
Set objPrice = rs("进价")
Set objUnit = rs("单位")
Set objDate = rs("进货日期") %>
<CENTER>
'使用循环语句将查询结果以表格形式输出
<TABLE BORDER=1><CAPTION>水果店库存量查询结果</CAPTION>
<% Do Until rs.EOF %>
<TR><TD><% Response.write ObjName %></TD><TD><% Response.write ObjKucun %></TD><TD><% Response.write ObjPrice %></TD><TD><% Response.write ObjUnit %></TD><TD><% Response.write ObjDate %></TD></TR>
<% rs.MoveNext %>
<% Loop %>
</TABLE></CENTER>
在上面的例子中,首先使用Connection对象与要操作的数据源建立连接;然后使用Command对象建立带五个参数的预定义查询命令(向库存表中添加一次采购记录),并两次以不同的参数值(葡萄和柿子)执行该查询命令;最后使用Recordset对象查询库存表中所有商品的库存信息,并以表格的形式输出。如果对VB的数据库编程比较熟悉,则会发现ADO与VB中的远程数据对象(RDO)比较相似。上例运行结果如图3所示。
与IDC一样,运行该数据库访问脚本的通常做法是在HTML文件中嵌入一个.asp文件的连接。例如,下面的HTML语句向Web服务器发出了请求,要求执行adotest.asp文件。
<A HREF="http://LocalHost/idctest/ado/adotest.asp">库存量查询</A>
三.远程数据服务(RDS)
RDS是IIS 4.0中新提出的概念,它是由ASP中原来的Advanced Data Connector(ADC)发展而来的。在IIS 4.0中,RDS与ADO集成到一起,使用同样的编程模型,提供访问远程数据库的功能。
ADO虽然能够提供非常强大的数据库访问功能,但是它不支持数据远程操作(Data Remoting)。换句话说,ADO只能执行查询并返回数据库查询的结果,这种结果是静态的,服务器上的数据库与客户端看到的数据没有“活的连接关系”。假如,客户端需要修改数据库中的数据,就必须构造修改数据的SQL语句,执行相应的查询动作。
而RDS就比ADO更进一步,它支持数据远程操作。它不仅能执行查询并返回数据库查询结果,而且这种结果是“动态的”, 服务器上的数据库与客户端看到的数据保持“活的连接关系”。即把服务器端的数据搬到客户端,在客户端修改数据后,调用一个数据库更新命令,就可以将客户端对数据的修改写回数据库,就象使用本地数据库一样。
由于RDS与ADO集成,RDS的底层是调用ADO来完成的,所以也可以将RDS理解为ADO的RDS,即ActiveX数据对象的远程数据服务。所以RDS同样具有ADO的易用性,区别仅在于RDS需要与数据绑定控件一同使用,比如Sheridan的ActiveX DataBound Grid控件。正如ADO类似于VB中的RDO一样,RDS也类似于VB中的远程数据控件(RDC)。下面是使用RDS提供客户端数据远程操作的例子:
<HTML><HEAD><TITLE>水果店库存查询结果</TITLE></HEAD>
<CENTER>水果商店库存表</CENTER>
<!--向HTML页面中插入Sheridan DataBound Grid 控件 -->
<CENTER><OBJECT CLASSID="CLSID:AC05DC80-7DF1-11d0-839E-00A024A94B3A"
CODEBASE="http://localhost/MSADC/ssdatb32.cab" ID="GRID" DATASRC="#ADC"
WIDTH=600 HEIGHT=150>
<PARAM NAME="AllowAddNew" VALUE="TRUE">
<PARAM NAME="AllowDelete" VALUE="TRUE">
<PARAM NAME="AllowUpdate" VALUE="TRUE"> </OBJECT>
<TABLE>
<!-- 提供三个文本框,输入数据库连接信息和查询命令-->
<TR><TD>服务器:<TD><INPUT NAME="Server" SIZE=70>
<TR><TD>数据库连接:<TD><INPUT NAME="Connect" SIZE=70>
<TR><TD>查询命令:<TD><INPUT NAME="Query" SIZE=70></TABLE>
<HR>
<!-- 提供客户端操作的命令按钮 -->
<INPUT TYPE=BUTTON NAME="Run" VALUE="运行">
<INPUT TYPE=BUTTON NAME="MoveFirst" VALUE="第一条">
<INPUT TYPE=BUTTON NAME="MovePrev" VALUE="上一条">
<INPUT TYPE=BUTTON NAME="MoveNext" VALUE="下一条">
<INPUT TYPE=BUTTON NAME="MoveLast" VALUE="最后一条">
<INPUT TYPE=BUTTON NAME="Submit" VALUE="提交更新">
<INPUT TYPE=BUTTON NAME="Cancel" VALUE="取消更新"></CENTER>
<!-- 在页面中插入RDS对象,名称为“ADC”,大小为1个像素(不可见) -->
<OBJECT CLASSID="clsid:BD96C556-65A3-11D0-983A-00C04FC29E33"
ID=ADC HEIGHT=1 WIDTH=1></OBJECT>
<SCRIPT LANGUAGE="VBScript">
<!-- 以下是各个命令按钮和窗体的事件处理 -->
SUB Window_OnLoad
<!-- 窗体加载事件的处理,设置三个文本框中的初始值 -->
Server.Value = "http://localhost"
Connect.Value = "DSN=KUCUN"
Query.Value = "SELECT * FROM 库存表"
End Sub
SUB Run_OnClick <!--“运行”命令的处理,执行文本框中的SQL命令 -->
ADC.Server = Server.Value
ADC.Connect = Connect.Value
ADC.SQL = Query.Value
ADC.Refresh
End Sub
SUB MoveFirst_OnClick
<!-- “第一条”命令的处理 -->
ADC.Recordset.MoveFirst
END SUB
SUB MoveNext_OnClick <!-- “下一条”命令的处理 -->
On Error Resume Next
ADC.Recordset.MoveNext
IF ERR.Number <> 0 THEN
ADC.Recordset.MoveLast
END IF
END SUB
<!-- “上一条”命令和“最后一条”命令的处理,略 -->
SUB Submit_OnClick
<!-- “提交更新”命令的处理 -->
ADC.SubmitChanges
ADC.Refresh
End Sub
SUB Cancel_OnClick
<!-- “取消更新”命令的处理 -->
ADC.CancelUpdate
ADC.Refresh
End Sub
</SCRIPT></BODY></HTML>
运行结果如图4所示。
所以,RDS在ADO的基础上通过绑定的数据显示和操作控件,提供给客户端更强的数据表现力和远程数据操纵功能。可以说RDS是目前基于Web的最好的远程数据库访问方式。
以上就是ASP访问数据库的三种方式,它们三者各有各的特色。IDC十分简单,使用.idc文件和.htx文件分别完成数据库的访问与输出任务,但是使用起来不灵活。ADO是ASP中推荐使用的方式,它功能强大,使用方便,是ASP的核心技术之一,但是它在提供用户远程操作数据库的功能时,比较复杂,实现起来有一定的难度。而RDS是基于ADO的,并提供远程操作数据库的强大工具。所以在需要提供高性能、高可靠性的远程数据操作功能时,RDS是更为理想的选择。