类型:转载 责任编辑:asp.net 日期:2007/05/23
热门软件下载:










页面导航:
正文内容:简介
在 active server pages (asp) 应用程序中显示大型记录集,很可能是您熟悉的一个问题。本文对此问题及其解决方案和示例代码进行了深入探讨,这个示例代码经过简单修改,就可以应用于您的具体情况。该示例代码被设计成服务器端的解决方案,它与浏览器无关。另外,我会指出您在设计自己的解决方案时需要考虑的问题。
问题
您的查询返回了一个大型记录集。需要提供一个简便方法来浏览这些结果,即在每页上只显示结果的子集。要有效的完成此项工作,需要对 activex(r) 数据对象 (ado) 和数据库如何协同工作有深入的了解。
解决方案
如何将您的记录集分成“页”,而不用大型的结果?所谓页,基本上就是您指定应当显示在一起的许多记录。例如,如果您的记录集中有 100 条记录,可能每页显示 10 条记录。
ado 提供了两种方法,pagesize 和 absolutepage。这些方法使您能够指定每页要显示的记录数,以及将游标定位于一页的开始。
打开记录集之后,基本步骤就是:
示例代码
下列示例代码说明了页面建立过程。借助它,您可以建立自己的解决方案的原型。在您自己的代码中,确保要完成下列步骤:
一定要通过更改连接字符串和 sql 语句来修改我的示例代码,以指向您的数据库。由于代码使用 ado 常数,如 aduserserver,一定要在您的 global.asa 文件中引用 ado typelibrary,或在 asp 页中包括 adovbs.inc 文件。请注意,在将项目引用设置为 microsoft ado 时,visual interdev(r) 会为您自动生成 typelibrary 引用。
注意该示例有两种方法可以提供导航栏:
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>
分析
设计分页解决方案时,需注意的几个问题:
以下是需要牢记的几点提示:
结论
分页是一项通用技术,许多 web 应用程序用它来提供浏览大量记录的好方法。在设计分页解决方案时,需要考虑一些问题,如,如何检索记录,需要提供什么类型的用户导航。尽管最好的解决方案取决于您的具体的应用程序,使用本文中的技术将帮助您作出更好的设计决策。