不同数据库分页

本文介绍了在ORACLE和SQLSERVER中实现分页查询的方法。对于ORACLE,使用ROWNUM进行分页控制;对于SQLSERVER,提供了三种分页方案,并对比了它们的效率。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

ORACLE分页

=========================================

分页的宗旨是控制查询出来的数据个数,下面这条语句对于Oracle分页已经足够了。
(注:该语句只能用于Oracle)

SELECT * FROM (SELECT AA.*, ROWNUM RN FROM (SELECT * FROM USERS ORDER BY ID DESC) AA WHERE ROWNUM <= 10) WHERE RN > 0

说明:
其中USERS为数据库表名
SELECT * FROMUSERS ORDER BY ID DESC
这一句是不进行分页的查询。
而ROWNUM <= 10和RN >0用于控制每页要显示的数据条数,我这里用ROWNUM <= 10和RN >0表示每页显示10条数据,那么要进入下一页,则ROWNUM <= 20和RN >10

上面的这两个数值只需要你在程序中动态传入值,例如在struts或servlet中动态传入两个参数就可以进行分页控制。

Oracle的rownum字段是个比较奇怪的字段。拿一张有26条记录的Test表来举例。 select * from Test where rownum >=1; select * from Test where rownum >=2; select * from Test where rownum <= 10; 第一条sql查出了26条记录,第二条sql一条记录也没查出。第三条sql查出10条记录。 导致这个的原因是因为rownum是个虚拟的字段,它是在记录输出的时候逐步产生的。 对第一条sql,第一条记录的rownum是1,满足条件被输出,因此第二条纪录的rownum就变成2,满足条件被输出,依此类推,就把所有纪录都查出来了。 对于第二条sql,第一条记录的rownum是1,不满足条件没被输出,因此第二条记录的rownum还是1,没满足条件没被输出,依此类推,所有纪录都没能被查出来。 对于第三条sql,第一条记录的rownum是1,满足条件被输出,因此第二条记录的rownum就递增为2,满足条件被输出,直到第11条及之后的所有记录的rownum变成了11,不满足条件没被输出。 所以要查询Test表第n条到第m条的记录,我们应该这样写: //对已形成的rownum进行过滤 select * from ( //先用一个select把待查sql包围起来,此时rownum已经形成 select row_.*, rownum rownum_ from ( select * from Test ) row_ ) where rownum_ <= m and rownum_ >= n;

SQLSERVER 分页

=========================================

分页方案一:(利用Not In和SELECT TOP分页)
语句形式:
SELECT TOP 10 *
FROM TestTable
WHERE (ID NOT IN
(SELECT TOP 20 id
FROM TestTable
ORDER BY id))
ORDER BY ID

SELECT TOP 页大小 *
FROM TestTable
WHERE (ID NOT IN
(SELECT TOP 页大小*页数 id
FROM 表
ORDER BY id))
ORDER BY ID
-------------------------------------
分页方案二:(利用ID大于多少和SELECT TOP分页)
语句形式:
SELECT TOP 10 *
FROM TestTable
WHERE (ID >
(SELECT MAX(id)
FROM (SELECT TOP 20 id
FROM TestTable
ORDER BY id) AS T))
ORDER BY ID

SELECT TOP 页大小 *
FROM TestTable
WHERE (ID >
(SELECT MAX(id)
FROM (SELECT TOP 页大小*页数 id
FROM 表
ORDER BY id) AS T))
ORDER BY ID

-------------------------------------
分页方案三:(利用SQL的游标存储过程分页)
create procedure XiaoZhengGe
@sqlstr nvarchar(4000), --查询字符串
@currentpage int,--第N页
@pagesize int--每页行数
as
set nocount on
declare @P1 int,--P1是游标的id
@rowcount int
exec sp_cursoropen @P1 output,@sqlstr,@scrollopt=1,@ccopt=1,@rowcount=@rowcount output
select ceiling(
1.0*@rowcount/@pagesize ) as 总页数--,@rowcount as 总行数,@currentpage as 当前页
set @currentpage=(@currentpage-1)*@pagesize+1
exec sp_cursorfetch @P1,16,@currentpage,@pagesize
exec sp_cursorclose @P1
set nocount off
其它的方案:如果没有主键,可以用临时表,也可以用方案三做,但是效率会低。
建议优化的时候,加上主键和索引,查询效率会提高。
通过SQL 查询分析器,显示比较:我的结论是:
分页方案二:(利用ID大于多少和SELECT TOP分页)效率最高,需要拼接SQL语句
分页方案一:(利用Not In和SELECT TOP分页) 效率次之,需要拼接SQL语句
分页方案三:(利用SQL的游标存储过程分页) 效率最差,但是最为通用
在实际情况中,要具体分析。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值