黑马程序员技术交流社区

标题: 【已解决】网页自动将数据库中的记录自动分页怎么做啊 [打印本页]

作者: 武剑峰    时间: 2012-6-15 14:50
标题: 【已解决】网页自动将数据库中的记录自动分页怎么做啊
本帖最后由 武剑峰 于 2012-6-19 10:30 编辑

因为数据库表(或视图)中记录条数太多(10W),一次加载即浪费资源又速度慢,于是想实现分页加载,每次只取规定条数,并在下边再规划出分页,用什么方法即简单又节省资源呢?并且单击对应的分页可以加载对应的记录
作者: 武剑峰    时间: 2012-6-15 14:55
对了我用的是sql2000的数据库
作者: 蒋春    时间: 2012-6-15 16:02
select top 10 * from Table_name where Col_name not in (select top PageIndex*10 id from Tabele_Name);
PageIndex是页索引,通过程序记录页索引这样能在数据库中查询出在需要的范围内的数据
页索引以0开始,如果是1开始在查询的时候就需要减一 (PageIndex-1)*10
如果是sql2005的话可以用rownum()函数实现分页
作者: 平建    时间: 2012-6-15 16:25
本帖最后由 平建 于 2012-6-15 16:28 编辑

给你个存储过程!!
代码

alter PROCEDURE Pages
@TableNames VARCHAR(200),     --表名,可以是多个表,但不能用别名
@PrimaryKey VARCHAR(100),     --主键,可以为空,但@Order为空时该值不能为空
@Fields     VARCHAR(800),         --要取出的字段,可以是多个表的字段,可以为空,为空表示select *
@PageSize INT,             --每页记录数
@CurrentPage INT,         --当前页,0表示第1页
@Filter VARCHAR(200) = '',     --条件,可以为空,不用填 where
@Order VARCHAR(200) = '' ,    --排序,可以为空,为空默认按主键升序排列,不用填 order by
@ResultCount varchar(24)
AS
BEGIN
declare @topRow varchar(12)
declare @tempPageSize varchar(12)
if(len(@Order)>0)
begin
set @Order=' order by '+@Order
end
else
begin
set @Order=''
end
if (len(@Filter)<1)
begin
set @Filter=' 1=1'
end
if(@CurrentPage-1<=0)
set @CurrentPage=0
if(len(rtrim(ltrim(@ResultCount)))>0)
set @ResultCount='set rowcount '+ltrim(rtrim(@ResultCount))
set @topRow= rtrim(ltrim(str(@PageSize*(@CurrentPage-1))))
set @tempPageSize= rtrim(ltrim(str(@PageSize)))
exec('
declare @temptable table(rownum int identity(1,1),Gid varchar(36))'+'
declare @datatable table(Gid varchar(36))'+'
declare @date datetime'+'
set @date=getdate()'+'
SET NOCOUNT ON '+'
'+@ResultCount+'
insert into @temptable(Gid) select '+@PrimaryKey+' from '+@TableNames+' where  '+@Filter+@Order+'
set rowcount '+@tempPageSize+'
insert into @datatable(Gid) select  Gid from @temptable where rownum>'+@topRow+'
select '+@Fields+' from '+@TableNames+' where '+@Filter+' and '+@PrimaryKey+' in (select  Gid from @datatable)'+@Order+'
set rowcount 0'+'
print(datediff(ms,@date,getdate()))')
--declare @datatable table(Gid varchar(12))'+'
---insert into @datatable(Gid) select  Gid from @temptable where rownum>'+@topRow+'
--set rowcount '+@tempPageSize+'
--+'set rowcount 0'
--print('insert into @temptable(Gid) select '+@PrimaryKey+' from '+@TableNames+' where  '+@Filter+@Order)
---print('select '+@Fields+' from '+@TableNames+' where '+@Filter+' and '+@PrimaryKey+' in(select Gid from @datatable) '+@Order)
end
GO

就像楼上说的如果是sql2005以上的用ROW_NUMBER()函数实现分页,效果非常好。
给你个数据看看
以下是利用本方法和传统利用Set RowCount方法存储过程的效率比较结果:

未建索引情况下:
500w数据: 存储过程1分20秒 , 新方法1分18秒
400w数据:存储过程47秒,新方法41秒
300w数据:存储过程35秒,新方法30秒
200w数据:存储过程25秒,新方法20秒
100W数据:存储过程12秒,新方法10秒
50W数据:存储过程 7秒,新方法 0秒

作者: 武剑峰    时间: 2012-6-15 22:28
谢谢了,明天上网后试试后再答复大家
作者: 黑马-杨鹏立    时间: 2012-6-16 01:03
最简单的方法可以用ListView绑定数据,把数据库的调用做得简单好用可以通过强类型数据集dataset来做,然后用ObjectDataSource绑定数据源(也就是你要用到的数据表,这里已经做成了数据集),再将ListView进行数据绑定。。。也就是绑定你绑定的ObjectDataSource,在对相应的属性进行设置
作者: 武剑峰    时间: 2012-6-19 10:22
呵呵,谢谢大家了,虽然访问速度还是不理想,但是功能基本实现了
作者: 武剑峰    时间: 2012-6-19 10:23
平建 发表于 2012-6-15 16:25
给你个存储过程!!
代码

本人水平有限,对存储过程不会用用但还是谢谢了
作者: 程艳伟    时间: 2012-6-22 19:15
用一个分页储蓄过程,网上这个到处都是,但是如过你的是sql2000的话,因为它没有那个自动加编号的函数,所以比较麻烦,所以我建议升级为sql2005,然后从网上找个分页储蓄过程,仔细分析一下就能自己用了,为了加快速度,记得加上索引哦
作者: 程艳伟    时间: 2012-6-22 19:16
武剑峰 发表于 2012-6-19 10:23
本人水平有限,对存储过程不会用用但还是谢谢了

储蓄过程就跟一个方法是一样的啊,有参数,有返回值,自己在网上看看就都明白了,别说怎么让人泄气的话:@




欢迎光临 黑马程序员技术交流社区 (http://bbs.itheima.com/) 黑马程序员IT技术论坛 X3.2