使用 Recordset 对象处理结果
为了检索数据、检查结果和更改数据库,ADO 提供了 Recordset 对象。正如名字所示,“Recordset”对象具有用来检索和显示数据库行(或叫“记录”)的功能,这取决于您的查询约束条件。“Recordset”对象保留由查询返回的每一条记录的位置,这样就能使您查看所有的结果,每次一条。
检索记录集
成功的 Web 数据应用程序既使用“Connection”对象来建立链接,又使用“Recordset”对象来处理返回的数据。通过综合使用这两种对象的一些特殊功能,开发出的数据库应用程序几乎可以执行所有的数据处理任务。例如,下面的服务器端脚本使用“Recordset”对象执行 SQL 的 SELECT 命令。此 SELECT 命令用来检索基于查询约束条件的信息集。此查询也包含 SQL WHERE 子句,用来将查询限制到一个指定的标准。在本例中,WHERE 子句将查询限制在 Customers 数据库表中姓氏字段包含 Smith 的所有记录。
<%
'建立数据源连接
strConnectionString = "Provider=Microsoft.Jet.OLEDB.4.0;Data Source=C:\Data\Employees.mdb"
Set cnn = Server.CreateObject("ADODB.Connection")
cnn.Open strConnectionString
'例示 Recordset 对象
Set rstCustomers = Server.CreateObject("ADODB.Recordset")
'使用 Open 方法打开记录集
'并使用通过 Connection 对象建立的连接。
strSQL = "SELECT FirstName, LastName FROM Customers WHERE LastName = 'Smith' "
rstCustomers.Open strSQL, cnn
'遍历记录集和显示结果
'并使用 MoveNext 方法递增记录位置。
Set objFirstName = rstCustomers("FirstName")
Set objLastName = rstCustomers("LastName")
Do Until rstCustomers.EOF
Response.Write objFirstName & " " & objLastName & "<BR>"
rstCustomers.MoveNext
Loop
%>
注意,在上例中,“Connection”对象建立数据库连接,而“Recordset”对象使用同一连接从数据库中检索结果。当需要精确配置建立数据库链接的方式时,该方法非常有用。例如,如果要指定在连接中止之前的时间延迟,可能需要使用“Connection”对象设置该属性。但是,如果只想使用 ADO 的默认连接属性建立连接,您可以使用“Recordset”对象的“Open”方法来建立链接:
<%
strConnectionString = "Provider=Microsoft.Jet.OLEDB.4.0;Data Source=C:\Data\Employees.mdb"
strSQL = "SELECT FirstName, LastName FROM Customers WHERE LastName = 'Smith' "
Set rstCustomers = Server.CreateObject("ADODB.Recordset")
'使用 Open 方法打开连接
'并使用通过 Connection 对象建立的连接。
rstCustomers.Open strSQL, strConnectionString
'遍历记录集,显示结果,
'并使用 MoveNext 方法递增记录位置。
Set objFirstName = rstCustomers("FirstName")
Set objLastName = rstCustomers("LastName")
Do Until rstCustomers.EOF
Response.Write objFirstName & " " & objLastName & "<BR>"
rstCustomers.MoveNext
Loop
%>
当使用“Recordset”对象的“Open”方法来建立连接时,实际上正在隐含地使用“Connection”对象保护链接的安全。详细信息,请参阅 Microsoft ActiveX 数据对象 (ADO) 文档,可在 Microsoft Universal Data Access Web 站点 http://www.microsoft.com/data/ 上找到该文档。
注意 要明显提高 ASP 数据库应用程序的性能,请考虑在“应用程序”状态中高速缓存记录集。详细信息,请参阅高速缓存数据。
统计记录集中返回的记录数有时候很有用。“Recordset”对象的“Open”方法使您能够指定可选的光标参数,以确定潜在提供者检索和浏览记录集的方法。通过给用来执行查询的语句添加 adOpenKeyset 光标参数,可以使客户端应用程序完全地浏览记录集。因此,应用程序可使用 RecordCount 属性精确地统计记录集中的记录数。请参看下面的示例:
<%
Set rs = Server.CreateObject("ADODB.Recordset")
rs.Open "SELECT * FROM NewOrders", "Provider=Microsoft.Jet.OLEDB.3.51;Data Source='C:\CustomerOrders\Orders.mdb'", adOpenKeyset, adLockOptimistic, adCmdText
'使用 Recordset 对象的 RecordCount 属性进行统计。
If rs.RecordCount >= 5 then
Response.Write "我们已经收到下面" & rs.RecordCount & "个新订单<BR>"
Do Until rs.EOF
Response.Write rs("CustomerFirstName") & " " & rs("CustomerLastName") & "<BR>"
Response.Write rs("AccountNumber") & "<BR>"
Response.Write rs("Quantity") & "<BR>"
Response.Write rs("DeliveryDate") & "<BR><BR>"
rs.MoveNext
Loop
Else
Response.Write "订单数少于 " & rs.RecordCount & "。"
End If
rs.Close
%>
使用 Command 对象改善查询
使用 ADO 的 Command 对象执行查询的方式与使用“Connection”和“Recordset”对象执行查询的方式一样,但是使用“Command”对象可以准备(或编译)对数据库源的查询,然后使用各种不同的值重复发送此查询。用这种方法编译查询的好处在于,当您需要重新发布修改过的已有查询时,可以大大地减少发布时间。另外,还可以留下部分 SQL 查询不进行定义,用到了在执行之前改变查询部分的选项。
“Command”对象的“Parameters”集合可以使您避免每次重新发布查询时都要重建查询的麻烦。例如,如果您需要定期更新基于 Web 的库存系统的供应和费用信息,就可以按照下面的方式预定义查询:
<%
'使用 Connection 对象打开连接注意,Command 对象
'并不具有用来建立连接的 Open 方法。
strConnectionString = "Provider=Microsoft.Jet.OLEDB.4.0;Data Source=C:\Data\Inventory.mdb"
Set cnn = Server.CreateObject("ADODB.Connection")
cnn.Open strConnectionString
'例示 Command 对象;使用 ActiveConnection 属性将
'连接附加到 Command 对象上。
Set cmn= Server.CreateObject("ADODB.Command")
Set cmn.ActiveConnection = cnn
'定义 SQL 查询。
cmn.CommandText = "INSERT INTO Inventory (Material, Quantity) VALUES (?, ?)"
'在 Command 对象首次执行之前保存在 CommandText 属性
'中指定的查询的预备(或预编译)版本。
cmn.Prepared = True
'定义查询参数配置信息。
cmn.Parameters.Append cmn.CreateParameter("material_type",adVarChar, ,255 )
cmn.Parameters.Append cmn.CreateParameter("quantity",adVarChar, ,255 )
'定义并执行第一个插入操作。
cmn("material_type") = "日光灯泡"
cmn("quantity") = "40"
cmn.Execute ,,adCmdText + adExecuteNoRecords
'定义并执行第二个插入操作。
cmn("material_type") = "保险丝"
cmn("quantity") = "600"
cmn.Execute ,,adCmdText + adExecuteNoRecords
.
.
.
%>
要点 ADO 参数(如 adCmdText)是一些简单变量,这意味着在使用数据访问脚本中的 ADO 参数之前需要先定义参数值。由于 ADO 使用了大量的参数,因此通过“组件类型库”来定义参数更容易些,组件类型库是包含所有 ADO 参数和常量定义的文件。有关实施 ADO 类型库的详细信息,请参阅使用变量和常量主题中的使用常量部分。
在上例中,您将注意到脚本使用不同的值重复构建和重新发布 SQL 查询,但并没有重新定义并重新发送查询到数据库源中。使用“Command”命令编译查询也有如下优点:可避免当将字符串和变量连接成 SQL 查询时引起问题。特别地,使用“Command”对象的“Parameter”集合,您可以避免那些与定义特定类型字符串、日期和时间变量相关的问题。例如,包含单引号 (') 的 SQL 查询值可能导致查询失败:
strSQL = "INSERT INTO Customers (FirstName, LastName) VALUES ('Robert','O'Hara')"
注意,姓氏“O'Hara”包含一个单引号,这与用来表示 SQL VALUES 关键字中数据的单引号冲突。通过将查询值约束为“Command”对象参数可以避免此类问题。
合并 HTML 表单和数据库访问
包含 HTML 表单的 Web 页可允许用户远程查询数据库并检索指定的信息。使用 ADO 您可以创建出非常简单的用来收集用户表单信息的脚本、创建自定义的数据库查询并将信息返回给用户。使用 ASP 的“Request”对象,您可以检索输入到 HTML 表单中的信息并将这些信息嵌入到 SQL 语句中。例如,下面的脚本块会将由 HTML 表单提供的信息插入到表中。脚本使用“Request”对象的“Form”集合来收集用户信息。
<%
'使用 Connection 对象打开连接Command 对象
'并不具有用来建立连接的 Open 方法。
strConnectionString = "Provider=Microsoft.Jet.OLEDB.4.0;Data Source=D:\CompanyCatalog\Seeds.mdb"
Set cnn = Server.CreateObject("ADODB.Connection")
cnn.Open strConnectionString
'例示 Command 对象
'并使用 ActiveConnection 属性附加对象
'连接附加到 Command 对象上。
Set cmn= Server.CreateObject("ADODB.Command")
Set cmn.ActiveConnection = cnn
'定义 SQL 查询。
cmn.CommandText = "INSERT INTO MySeedsTable (Type) VALUES (?)"
'定义查询参数配置信息。
cmn.Parameters.Append cmn.CreateParameter("type",adVarChar, ,255)
'指派输入值并执行更新。
cmn("type") = Request.Form("SeedType")
cmn.Execute ,,adCmdText + adExecuteNoRecords
%>
有关表单和使用 ASP“Request”对象的详细信息,请参阅处理用户输入。
管理数据库连接
设计完善的 Web 数据库应用程序(如服务成千上万个客户的联机订购输入应用程序)的一个主要挑战就是如何正确管理数据库连接。打开并维护数据库连接,尤其是当没有信息传输时也要打开和维护,会严重消耗数据库服务器的资源并导致连接性问题。设计良好的 Web 数据库应用程序可重复利用数据库连接并补偿因网络通信量导致的延迟。
超时连接
数据库服务器当活动突然激增时会产生积压,同时大大增加建立数据库连接所需的时间。因此,过多的连接延迟会降低数据库应用程序的性能。
使用“Connection”对象的“ConnectionTimeout”可以限制应用程序在放弃连接尝试并发布错误消息之前等待的时间数。例如,下面的脚本将“ConnectionTimeout”属性设置为在取消连接尝试之前等待 20 秒。
Set cnn = Server.CreateObject("ADODB.Connection")
cnn.ConnectionTimeout = 20
cnn.Open "Provider=Microsoft.Jet.OLEDB.4.0;Data Source=C:\Data\Inventory.mdb"
“ConnectionTimeout”属性默认为 30 秒。
注意 在将“ConnectionTimeout”属性并入数据库应用程序之前,请确保您的连接提供者和数据源支持该属性。
共用连接
连接池可使您的 Web 应用程序使用“池”中的连接,“池”指的是包含许多不需要重新建立的自由连接的容器。创建连接并放入连接池中后,应用程序可以重复使用该连接而不必执行连接进程。这可明显地提高性能,特别是在应用程序通过网络连接或需要重复连接和断开的情况下更是如此。另外,共用的连接可被多个应用程序重复使用。
OLE DB 会话池
OLE DB 具有一个共用特性,称为“会话池”,用来提高大型 Web 数据库应用程序的活动性能。会话池保护连接安全和一些其他属性。共用的连接只在连接两端提出匹配的请求时才可重新使用。默认情况下,Microsoft SQL server 和 Oracle 的 OLE DB 提供者支持会话池。这意味着并不需要配置应用程序、服务器或数据库即可使用会话池。然而,如果提供者默认情况下不支持会话池,则需要创建注册表设置以启用会话池。关于会话池的详细信息,请参阅 OLE DB 2.0 Software Development Kit (SDK) 文档。
ODBC 连接池
如果希望 ODBC 驱动程序分享连接池,您必须配置特定的数据库驱动程序,然后在 Windows 注册表中设置驱动程序的“CPTimeout”属性。“CPTimeout”属性确定连接在连接池中保留的时间长度。如果连接在池中保留的时间超过“CPTimeout”设置的持续时间,连接将关闭并从池中删除。“CPTimeout”的默认值是 60 秒。
通过创建带有下面设置的注册表键值,您可以有选择地设置“CPTimeout”属性以启用特定 ODBC 数据库驱动程序的连接池:
\HKEY_LOCAL_MACHINE\SOFTWARE\ODBC\ODBCINST.INI\driver-name\CPTimeout = 超时数
(REG_SZ, 以秒为单位)
例如,下面的键值将 SQL Server 驱动程序的连接池超时设置为 180 秒(3 分钟)。
\HKEY_LOCAL_MACHINE\SOFTWARE\ODBC\ODBCINST.INI\SQL Server\CPTimeout = 180
注意 默认情况下,Web 服务器激活 SQL Server 的连接池并将“CPTimeout”设置为 60 秒。
使用跨多页的连接
虽然可以通过将连接储存在 ASP 的“Application”对象中来重复使用跨多页的连接,但这样做可能导致不必要地保持打开的连接,并且可能损害使用连接池的优势。如果有许多用户需要连接到同一 ASP 应用程序,一种更好的方法是重复使用跨多个 Web 页的数据库连接字符串,只需将字符串放置到 ASP 的“Application”对象中即可。例如,您可以在 Global.asa 文件的 Application_OnStart 事件过程中指定连接字符串,如下面的脚本所示:
Application("ConnectionString") = "Provider=Microsoft.Jet.OLEDB.4.0;Data Source=C:\Data\Inventory.mdb"
然后在每一个访问数据库的 ASP 文件中,写入
<OBJECT RUNAT=SERVER ID=cnn PROGID="ADODB.Connection"></OBJECT>
以创建该页的连接对象实例,并使用脚本
cnn.Open Application("ConnectionString")
打开该连接。要关闭连接,在该页的末尾可以使用
cnn.Close
在个别用户需要重复使用跨多个 Web 页连接的情况下,您将发现使用“Session”对象储存连接字符串比使用“Application”对象更具优势。
关闭连接
要充分利用连接池,请尽可能显式关闭数据库连接。默认情况下,连接在脚本执行完后终止。然而,通过显式关闭脚本已不再需要的连接,您可以减少对数据库服务器的要求,并使得其他用户可以使用该连接。
可以使用“Connection”对象的“Close”方法显式终止“Connection”对象和数据库之间的连接。下面的脚本将打开和关闭连接:
<%
strConnectionString = "Provider=Microsoft.Jet.OLEDB.4.0;Data Source=C:\Data\Inventory.mdb"
Set cnn = Server.CreateObject("ADODB.Connection")
cnn.Open strConnectionString
cnn.Close
%>
--------------------------------------------------------------------------------
© 1997-1999 Microsoft Corporation。保留所有权利。
……