资讯   |   开发   |   选机中心   |   产品大全 | IBM | 惠普 | 联想 | 戴尔 | 苹果 | 神舟
更多: | 华硕 | 明基 | 方正 | 紫光 | TCL | 夏新 | 联宝 | 宏碁 | 七喜 | 长城 | 清华同方 | 海尔 | 三星 | 东芝 | 索尼 | 富士通 | LG | 技术 | ddnoon
当前位置:笔记本 > 编程开发 >
Advertisement
文章正文

通过ASP记录进行分页_编程

类型:转载   责任编辑:asp.net   日期:2007/05/23


热门软件下载:


   
  • 三种禁用FileSystemObject组件的方法 
  • MD5算法研究 
  • 黑客案例--浏览器执行exe文件的探讨 
  • ASP、IIS的安全漏洞 
  • 堵住ASP漏洞 
  • HOWTO:GetRecordsandReturnValuefromStoredProcUsingDTCs 
  • MTS管理自动化 
  • 处理ASP请求的内部讨论 
  • iis漏洞检查 
  • IEWebBrowser组件的execWB方法 
  • 页面导航:

    正文内容:

    简介

    在 active server pages (asp) 应用程序中显示大型记录集,很可能是您熟悉的一个问题。本文对此问题及其解决方案和示例代码进行了深入探讨,这个示例代码经过简单修改,就可以应用于您的具体情况。该示例代码被设计成服务器端的解决方案,它与浏览器无关。另外,我会指出您在设计自己的解决方案时需要考虑的问题。

    问题

    您的查询返回了一个大型记录集。需要提供一个简便方法来浏览这些结果,即在每页上只显示结果的子集。要有效的完成此项工作,需要对 activex(r) 数据对象 (ado) 和数据库如何协同工作有深入的了解。

    解决方案

    如何将您的记录集分成“页”,而不用大型的结果?所谓页,基本上就是您指定应当显示在一起的许多记录。例如,如果您的记录集中有 100 条记录,可能每页显示 10 条记录。

    ado 提供了两种方法,pagesizeabsolutepage。这些方法使您能够指定每页要显示的记录数,以及将游标定位于一页的开始。

    打开记录集之后,基本步骤就是:

    1. 为该记录集指定 pagesize。它表示每页要显示的记录数。
    2. 指定该记录集的 absolutepage。这将记录指针移到页的序列中,给定页的开始处。
    3. 显示记录页。要完成这一步,您要用设置的 pagesize 次数循环整个记录集,或者直到到达文件的末尾。

    示例代码

    下列示例代码说明了页面建立过程。借助它,您可以建立自己的解决方案的原型。在您自己的代码中,确保要完成下列步骤:

    • 添加错误处理。
    • 添加对查询返回的记录数的限制。
    • 用条件过滤记录。(如,建立 where 子句)。
    • 使用存储过程或视图。

    一定要通过更改连接字符串和 sql 语句来修改我的示例代码,以指向您的数据库。由于代码使用 ado 常数,如 aduserserver,一定要在您的 global.asa 文件中引用 ado typelibrary,或在 asp 页中包括 adovbs.inc 文件。请注意,在将项目引用设置为 microsoft ado 时,visual interdev(r) 会为您自动生成 typelibrary 引用。

    注意该示例有两种方法可以提供导航栏:

    • shownavbar。 它为用户提供了带着记录计数一起跳到指定页的方法(见图 1)。为实现这一步,它使用了 recordcountpagecount 属性。
    • 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>
    

    分析

    设计分页解决方案时,需注意的几个问题:

    • 游标定位问题。如果使用客户端游标,每次打开记录集时,将读取所有的记录。因此,由于读取了所有的记录,以后访问 recordcountpagecount 属性时将很快。如果您使用服务器端游标,将只检索需要的记录。您可以通过 cachesize 属性指定一次要读取的记录数来提高性能。然而,如果您使用服务器端游标,和 recordcountpagecount 属性,则将读取所有的记录,性能得不到提高。必须在具有更多信息和更丰富导航的用户界面,与检索所有记录的性能影响之间折衷。
    • 使用服务器端游标时,cursortype 属性必须是 adopenstaticadopenkeyset,才能使用分页。
    • 分页并非总是最好的用户页面。它可能仅适用于用户正从搜索引擎扫描结果或浏览产品目录的情况。
    • 试将记录分类,以使更相关的记录出现在前几页中(例如,使用 sql 的 order by 子句)。用户所能做的就这么多。
    • 只检索需要显示的列(即,避免 select *)。
    • 只检索需要显示的记录。确保过滤的条件(即,使用 where 子句)。

    以下是需要牢记的几点提示:

    • 将您的逻辑封装在方法中。使用方法可将表示逻辑和数据访问逻辑分离,这就简化了将代码装入 windows 脚本组件、visual basic 脚本编辑 (vbscript) 类或组件的工作。改变功能更容易了,代码维护也得以改进。测试和调试也因可以注释和取消注释方法调用而得到改进。
    • 与包括 adovbs.inc 相比,引用 ado 的 typelibrary 是更好的解决方案。这是因为 asp 在处理包含文件时,是将整个文件读入内存,而不是只读入它需要的部分。

    结论

    分页是一项通用技术,许多 web 应用程序用它来提供浏览大量记录的好方法。在设计分页解决方案时,需要考虑一些问题,如,如何检索记录,需要提供什么类型的用户导航。尽管最好的解决方案取决于您的具体的应用程序,使用本文中的技术将帮助您作出更好的设计决策。


     

     
    热门推荐笔记本: IBM笔记本
    相关文章:
    webmaster:popbb@126.com   最佳浏览:1024X768 MSIE
    ©2007 popbb.net All Rights Reserved