| 广告招租,e-mail:yesize@hotmail.com
|
|
广告招租,e-mail:yesize@hotmail.com
通过 ASP 记录进行分页 J.D. Meier 目录 -------------------------------------------------------------------------------- 1、简介 2、问题 3、解决方案 4、示例代码 5、分析 6、结论 -------------------------------------------------------------------------------- 简介 在 Active Server Pages (ASP) 应用程序中显示大型记录集,很可能是您熟悉的一个问题。本文对此问题及其解决方案和示例代码进行了深入探讨,这个示例代码经过简单修改,就可以应用于您的具体情况。该示例代码被设计成服务器端的解决方案,它与浏览器无关。另外,我会指出您在设计自己的解决方案时需要考虑的问题。 问题 您的查询返回了一个大型记录集。需要提供一个简便方法来浏览这些结果,即在每页上只显示结果的子集。要有效的完成此项工作,需要对 ActiveX(R) 数据对象 (ADO) 和数据库如何协同工作有深入的了解。 解决方案 如何将您的记录集分成“页”,而不用大型的结果?所谓页,基本上就是您指定应当显示在一起的许多记录。例如,如果您的记录集中有 100 条记录,可能每页显示 10 条记录。 ADO 提供了两种方法,PageSize 和 AbsolutePage。这些方法使您能够指定每页要显示的记录数,以及将游标定位于一页的开始。 打开记录集之后,基本步骤就是: 为该记录集指定 PageSize。它表示每页要显示的记录数。 指定该记录集的 AbsolutePage。这将记录指针移到页的序列中,给定页的开始处。 显示记录页。要完成这一步,您要用设置的 PageSize 次数循环整个记录集,或者直到到达文件的末尾。 示例代码 下列示例代码说明了页面建立过程。借助它,您可以建立自己的解决方案的原型。在您自己的代码中,确保要完成下列步骤: 添加错误处理。 添加对查询返回的记录数的限制。 用条件过滤记录。(如,建立 WHERE 子句)。 使用存储过程或视图。 一定要通过更改连接字符串和 SQL 语句来修改我的示例代码,以指向您的数据库。由于代码使用 ADO 常数,如 adUserServer,一定要在您的 Global.asa 文件中引用 ADO TypeLibrary,或在 ASP 页中包括 ADOVBS.INC 文件。请注意,在将项目引用设置为 Microsoft ADO 时,Visual InterDev(R) 会为您自动生成 TypeLibrary 引用。 注意该示例有两种方法可以提供导航栏: ShowNavBar。 它为用户提供了带着记录计数一起跳到指定页的方法(见图 1)。为实现这一步,它使用了 RecordCount 和 PageCount 属性。 ShowNavBarFast。 该方法不提供跳转到指定页的能力,也不提供记录计数,但可以通过 CacheSize 属性控制取回的记录数(见图 2)。 PageThroughRs.Asp <%@ Language=VBScript %> <% Option Explicit %> <SCRIPT LANGUAGE=VBScript RUNAT=SERVER> 确保引用 ADO Typelib 或使用 ADOVBS.Inc Dim iPageNum, iRowsPerPage Main Sub Main() Dim rst Dim sSQL, sConnString If Request.QueryString(iPageNum) = Then iPageNum = 1 Else iPageNum = Request.QueryString(iPageNum) iPageNum = CInt(iPageNum) End If iRowsPerPage = 10 sConnString = Provider=SQLOLEDB.1;password=Xyz123;user id=WebUser; & _ Initial Catalog=NorthWind;Data Source=MySQLServer; & _ network=dbmssocn; 下列 SQL 从 SQL 视图中检索所有列。 要优化性能: - 使用存储过程、视图或在 SELECT 中指定列 - 使用限制返回的记录的条件(例如,WHERE 子句) sSQL = SELECT CategoryName, ProductName, QuantityPerUnit, sSQL = sSQL & UnitsInStock, Discontinued sSQL = sSQL & FROM [Products By Category] Set rst = GetRecords(sConnString, sSQL) WriteTableHeader rst WriteTableBody rst, iRowsPerPage, iPageNum ShowNavBar rst ShowFastNavBar 方法不使用 RecordCount 或 PageCount,所以它重试的记录数仅等于 记录集的 CacheSize 指定的数量。 ShowFastNavBar rst CleanUp rst End Sub Function GetRecords(sConnString, sSQL) Dim cnn Dim rst set cnn = Server.CreateObject(ADODB.CONNECTION) cnn.ConnectionString = sConnString nn.Open Set rst = Server.CreateObject(ADODB.RECORDSET) Set rst.ActiveConnection = cnn 当记录集打开时,adUseClient 的 CursorLocation 将检索所有的记录。 adUseServer 允许沿用 CacheSize rst.CursorLocation = adUseServer 在使用服务器端游标时,CacheSize 限制了取回的行数。我们将只抓取正在显示的 的记录的数目 - iRowsPerPage rst.CacheSize = iRowsPerPage rst.Open sSQL,,adOpenStatic, adLockReadOnly牋? Set GetRecords = rst end Function Sub WriteTableHeader(rst) Dim fld Response.Write <TABLE WIDTH=80% BORDER=1> Response.Write <TR> 建立表的列标题 For Each fld in rst.Fields Response.Write <TD><B> & fld.Name & </B></TD> Next Response.Write </TR> End Sub Sub WriteTableBody(rst, iRowsPerPage, iPageNum) Dim iLoop Dim fld iLoop = 1 rst.PageSize = iRowsPerPage rst.AbsolutePage = iPageNum 写出记录的当前页 Do While (Not rst.EOF) and (iLoop <= iRowsPerPage) Response.Write <TR> For Each fld in rst.Fields Response.Write <TD> & fld.value & </TD> Next iLoop = iLoop + 1 rst.MoveNext Response.Write </TR> Loop Response.Write </TABLE> End Sub Sub ShowNavBar(rst) Dim iPageCount Dim iLoop Dim sScriptName 本版本提供了更丰富的用户导航,但是 依赖于 RecordCount 和 PageCount, 它抵消了为服务器端游标 指定 CacheSize 的好处。 Response.Write <BR><BR> sScriptName = Request.ServerVariables(SCRIPT_NAME) If iPageNum > 1 Then Response.Write <a href= & sScriptName & ?iPageNum= Response.Write (iPageNum -1) & ><< Previous</a> End If iPageCount = rst.PageCount Do Until iLoop > iPageCount f iLoop = iPageNum Then Response.Write <B> & CStr(iLoop) & </B> Else Response.Write <a href= & sScriptName & ?iPageNum= & _ Cstr(iLoop) & > & iLoop & </a> End If iLoop = iLoop + 1 Loop If Not rst.EOF Then Response.Write <a href= & sScriptName & ?iPageNum= Response.Write (iPageNum +1) & > Next >></a><BR> Else Response.Write <BR> End If Response.Write Page & iPageNum & of & iPageCount & <BR> Response.Write rst.RecordCount & Records 牋? End Sub Sub ShowFastNavBar(rst) Dim iPageCount Dim iLoop Dim sScriptName 在指定 CacheSize 和使用服务器端游标时, 该方法特别有效,因为它不使用 RecordCount 和 PageCount。需要用户具有经验。 Response.Write <BR><BR> sScriptName = Request.ServerVariables(SCRIPT_NAME) If iPageNum > 1 Then Response.Write <a href= & sScriptName & ?iPageNum= Response.Write (iPageNum -1) & ><< Previous</a> End If If Not rst.EOF Then Response.Write <a href= & sScriptName & ?iPageNum= Response.Write (iPageNum +1) & > Next >></a><BR> Else Response.Write <BR> End If Response.Write Page & iPageNum End Sub Sub CleanUp(rst) If Not rst Is Nothing then If rst.state = adStateOpen then rst.close set rst = nothing End If End Sub </SCRIPT> 分析 设计分页解决方案时,需注意的几个问题: 游标定位问题。如果使用客户端游标,每次打开记录集时,将读取所有的记录。因此,由于读取了所有的记录,以后访问 RecordCount 或 PageCount 属性时将很快。如果您使用服务器端游标,将只检索需要的记录。您可以通过 CacheSize 属性指定一次要读取的记录数来提高性能。然而,如果您使用服务器端游标,和 RecordCount 或 PageCount 属性,则将读取所有的记录,性能得不到提高。必须在具有更多信息和更丰富导航的用户界面,与检索所有记录的性能影响之间折衷。 使用服务器端游标时,CursorType 属性必须是 adOpenStatic 或 adOpenKeyset,才能使用分页。 分页并非总是最好的用户页面。它可能仅适用于用户正从搜索引擎扫描结果或浏览产品目录的情况。 试将记录分类,以使更相关的记录出现在前几页中(例如,使用 SQL 的 ORDER BY 子句)。用户所能做的就这么多。 只检索需要显示的列(即,避免 SELECT *)。 只检索需要显示的记录。确保过滤的条件(即,使用 WHERE 子句)。 以下是需要牢记的几点提示: 将您的逻辑封装在方法中。使用方法可将表示逻辑和数据访问逻辑分离,这就简化了将代码装入 Windows 脚本组件、Visual Basic 脚本编辑 (VBScript) 类或组件的工作。改变功能更容易了,代码维护也得以改进。测试和调试也因可以注释和取消注释方法调用而得到改进。 与包括 ADOVBS.INC 相比,引用 ADO 的 TypeLibrary 是更好的解决方案。这是因为 ASP 在处理包含文件时,是将整个文件读入内存,而不是只读入它需要的部分。 结论 分页是一项通用技术,许多 Web 应用程序用它来提供浏览大量记录的好方法。在设计分页解决方案时,需要考虑一些问题,如,如何检索记录,需要提供什么类型的用户导航。尽管最好的解决方案取决于您的具体的应用程序,使用本文中的技术将帮助您作出更好的设计决策
版权说明:作品来源于网上,版权归作者所有,如果无意中侵犯了您的版权,请来信告知,本站将在3个工作日内删除。yesize@hotmail.com |
|