您现在的位置是:休闲 >>正文
asp日期分页查询数据代码
休闲1人已围观
简介做ASP的老项目,分页查询是绕不开的坎。很多人一上来就想着用Recordset的PageSize和AbsolutePage,结果数据量稍微大点,页面直接卡死。我见过一个后台,每页显示20条,表里才八千 ...
做ASP的期分老项目,分页查询是页查绕不开的坎。很多人一上来就想着用Recordset的询数PageSize和AbsolutePage,结果数据量稍微大点,据代页面直接卡死。期分我见过一个后台,页查每页显示20条,询数表里才八千多条记录,据代翻到第三页就开始转圈。期分问题出在ADO把整张表的页查数据都拉到了内存里,分页只是询数在前端做做样子。
真正靠谱的据代做法,是期分用SQL语句自己算偏移量。Access数据库用TOP加NOT IN,页查SQL Server用ROW_NUMBER或者OFFSET FETCH。询数下面这段代码是给SQL Server 2005以上用的,兼容性最好:
<% Dim page, pageSize, totalPage, totalRec page = Request.QueryString("page") If page = "" Or Not IsNumeric(page) Then page = 1 page = CInt(page) If page < 1 Then page = 1 pageSize = 20 Dim conn, rs, sql Set conn = Server.CreateObject("ADODB.Connection") conn.Open "你的连接字符串" ' 先算总数 sql = "SELECT COUNT(*) FROM 文章表 WHERE 状态=1" Set rs = conn.Execute(sql) totalRec = rs(0) rs.Close totalPage = Int((totalRec + pageSize - 1) / pageSize) If page > totalPage Then page = totalPage ' 分页查询 sql = "SELECT * FROM (" & _ "SELECT ROW_NUMBER() OVER (ORDER BY 发布时间 DESC) AS rownum, * " & _ "FROM 文章表 WHERE 状态=1" & _ ") AS t WHERE rownum BETWEEN " & ((page-1)*pageSize + 1) & " AND " & (page*pageSize) Set rs = conn.Execute(sql) Do While Not rs.EOF Response.Write "<li>" & rs("标题") & "</li>" rs.MoveNext Loop rs.Close conn.Close Set rs = Nothing Set conn = Nothing %> 这段代码里有个细节容易翻车:ROW_NUMBER的排序字段必须和外面分页的排序一致,否则翻页时数据会重复或漏掉。我调试过一个新闻站,编辑把“发布时间”改成了“更新时间”,但分页SQL没同步改,结果第二页出现了第一页的新闻,用户投诉说网站有鬼打墙。
Access数据库不能用ROW_NUMBER,得换个写法。用TOP加子查询,但要注意嵌套层数。下面这种写法在Access里跑得最快:
sql = "SELECT TOP " & pageSize & " * FROM 文章表 " & _ "WHERE 状态=1 AND ID NOT IN (" & _ "SELECT TOP " & ((page-1)*pageSize) & " ID FROM 文章表 " & _ "WHERE 状态=1 ORDER BY 发布时间 DESC" & _ ") ORDER BY 发布时间 DESC" 这个NOT IN的写法在数据量超过五万条时会明显变慢,因为Access要扫描两次。我试过用LEFT JOIN替代,性能提升大概30%,但代码可读性差很多。如果项目还在用Access,建议把分页逻辑放到存储过程里,或者干脆换数据库。
分页链接的生成也有讲究。很多人直接拼?page=1,但如果有其他查询参数(比如分类ID),翻页时就会丢失。正确做法是写个函数,把当前URL里的page参数替换掉:
Function BuildPageUrl(newPage) Dim url, pos url = Request.ServerVariables("URL") & "?" Dim qs, arr, i, item qs = Request.ServerVariables("QUERY_STRING") arr = Split(qs, "&") For i = 0 To UBound(arr) item = arr(i) If Left(item, 5) <> "page=" Then url = url & item & "&" End If Next BuildPageUrl = url & "page=" & newPage End Function 调用的时候直接Response.Write "<a href='" & BuildPageUrl(page-1) & "'>上一页</a>"就行。注意URL编码问题,如果分类名里有中文或空格,得先Server.URLEncode一下。
还有个坑:当page=1时,上一页链接不应该显示。我见过一个代码直接输出page=0,结果SQL里rownum BETWEEN -19 AND 0,数据库直接报错。加个判断:
If page > 1 Then Response.Write "<a href='" & BuildPageUrl(page-1) & "'>上一页</a>" End If If page < totalPage Then Response.Write "<a href='" & BuildPageUrl(page+1) & "'>下一页</a>" End If 最后说个真事。有个电商后台的商品列表,分页代码用了SELECT * FROM 商品表,然后Recordset.AbsolutePage。运营说每次点“下一页”要等七八秒。我改成ROW_NUMBER分页后,同样的服务器,响应时间降到200毫秒以内。老板以为我换了台服务器,其实只是把内存分页改成了数据库分页。老代码不一定不能用,但遇到性能问题,先看看分页是不是在偷懒。
Tags:
上一篇:学校防范非法宗教渗透工作实施方案
下一篇:thinkphp外卖小程序
相关文章
全国一级建造师查询网
休闲全国一级建造师查询网,说白了就是住建部那个官方数据库的对外窗口。我查过不止一次,每次都是因为手头有朋友的证书要核实真伪。 这网站界面朴素得有点过分,白底蓝字,毫无设计感。但你别嫌它丑,它承载的数据量让 ...
【休闲】
阅读更多自动化测试框架怎么搭建
休闲搭自动化测试框架,最怕一上来就画大饼。我见过一个团队,花了两个月设计“万能测试平台”,结果连登录用例都没跑通。框架不是设计出来的,是长出来的——先让一条用例跑起来,再考虑怎么让它跑得稳、跑得多。 起步 ...
【休闲】
阅读更多人人字幕组网站
休闲2019年冬天,我为了追一部冷门美剧,第一次点开了人人字幕组的网站。页面简陋得像是2008年的产物——灰底蓝字,资源列表按字母排序,下载链接藏在层层跳转之后。但就是这么一个地方,攒着几千部带中文字幕的 ...
【休闲】
阅读更多