视频1 视频21 视频41 视频61 视频文章1 视频文章21 视频文章41 视频文章61 推荐1 推荐3 推荐5 推荐7 推荐9 推荐11 推荐13 推荐15 推荐17 推荐19 推荐21 推荐23 推荐25 推荐27 推荐29 推荐31 推荐33 推荐35 推荐37 推荐39 推荐41 推荐43 推荐45 推荐47 推荐49 关键词1 关键词101 关键词201 关键词301 关键词401 关键词501 关键词601 关键词701 关键词801 关键词901 关键词1001 关键词1101 关键词1201 关键词1301 关键词1401 关键词1501 关键词1601 关键词1701 关键词1801 关键词1901 视频扩展1 视频扩展6 视频扩展11 视频扩展16 文章1 文章201 文章401 文章601 文章801 文章1001 资讯1 资讯501 资讯1001 资讯1501 标签1 标签501 标签1001 关键词1 关键词501 关键词1001 关键词1501 专题2001
SQLServer分页存储过程研究
2020-11-09 08:18:13 责编:小采
文档


http://www.webdiyer.com/Controls/AspNetPager/SpGenerator 生成SQL Server分页 存储 过程 SQL SEVER 2005以上版本: create procedure GetCasesByProjectID (@projectID nvarchar(50), @pagesize int, @pageindex int, @docount bit) as if(@docount=1) sel

http://www.webdiyer.com/Controls/AspNetPager/SpGenerator 生成SQL Server分页存储过程

SQL SEVER 2005以上版本:

create procedure GetCasesByProjectID
(@projectID nvarchar(50),
@pagesize int,
@pageindex int,
@docount bit)
as

if(@docount=1)
select count(*) from GenAccidentCase where gensitebasicid = @projectid
else
begin
with temptbl as (
SELECT ROW_NUMBER() OVER (ORDER BY AccidentDate desc)AS Row, * from GenAccidentCase O where gensitebasicid = @projectid)
SELECT * FROM temptbl where Row between (@pageindex-1)*@pagesize+1 and (@pageindex-1)*@pagesize+@pagesize
end

SQL SEVER 2000 版本:

create procedure GetCasesByProjectID
(@projectID nvarchar(50),
@pagesize int,
@pageindex int,
@docount bit)
as
set nocount on
if(@docount=1)
select count(*) from GenAccidentCase where gensitebasicid = @projectid
else
begin
declare @indextable table(id int identity(1,1),nid int)
declare @PageLowerBound int
declare @PageUpperBound int
set @PageLowerBound=(@pageindex-1)*@pagesize
set @PageUpperBound=@PageLowerBound+@pagesize
set rowcount @PageUpperBound
insert into @indextable(nid) select genAccidentCaseID from GenAccidentCase where gensitebasicid = @projectid order by AccidentDate desc
select * from GenAccidentCase O,@indextable t where O.genAccidentCaseID=t.nid
and t.id between @PageLowerBound+1 and @PageUpperBound order by t.id
end
set nocount off

企它参考:

CREATE procedure pagination1
(@pagesize int, --页面大小,如每页存储20条记录
@pageindex int --当前页码)
as set nocount on
begin
declare @indextable table(id int identity(1,1),nid int) --定义表变量
declare @PageLowerBound int --定义此页的底码
declare @PageUpperBound int --定义此页的顶码
set @PageLowerBound=(@pageindex-1)*@pagesize
set @PageUpperBound=@PageLowerBound+@pagesize
set rowcount @PageUpperBound
insert into @indextable(nid) select gid from TGongwen where fariqi >dateadd(day,-365,getdate()) order by fariqi desc
select O.gid,O.mid,O.title,O.fadanwei,O.fariqi from TGongwen O,@indextable t where O.gid=t.nid
and t.id>@PageLowerBound and t.id<=@PageUpperBound order by t.id
end
set nocount off

  文章中的点评:

  以上存储过程运用了SQL SERVER的最新技术――表变量。应该说这个存储过程也是一个非常优秀的分页存储过程。当然,在这个过程中,您也可以把其中的表变量写成临时表:CREATE TABLE #Temp。但很明显,在SQL SERVER中,用临时表是没有用表变量快的。所以笔者刚开始使用这个存储过程时,感觉非常的不错,速度也比原来的ADO的好。但后来,我又发现了比此方法更好的方法。

  从感觉上讲,效率不是太高。

  2. not in 的方法:

  从publish 表中取出第 n 条到第 m 条的记录:

  SELECT TOP m-n+1 * FROM publish WHERE (id NOT IN (SELECT TOP n-1 id FROM publish))

  id 为publish 表的关键字

  文章中的点评:

  我当时看到这篇文章的时候,真的是精神为之一振,觉得思路非常得好。等到后来,我在作办公自动化系统(ASP.NET+ C#+SQL SERVER)的时候,忽然想起了这篇文章,我想如果把这个语句改造一下,这就可能是一个非常好的分页存储过程于是我就满网上找这篇文章,没想到,文章还没找到,却找到了一篇根据此语句写的一个分页存储过程,这个存储过程也是目前较为流行的一种分页存储过程。

  使用了 not in 而 not in 是无法使用索引的,所以从效率上讲还是差了一点。

  3. max 的方法:

select top 页大小 * from table1 where id>
(select max (id) from
(select top ((页码-1)*页大小) id from table1 order by id) as T)
order by id

  文章中的点评:

  我们知道,几乎任何字段,我们都可以通过max(字段)或min(字段)来提取某个字段中的最大或最小值,所以如果这个字段不重复,那么就可以利用这些不重复的字段的max或min作为分水岭,使其成为分页算法中分开每页的参照物。在这里,我们可以用操作符“>”或“<”号来完成这个使命,使查询语句符合SARG形式。如:

  Select top 10 * from table1 where id>200

  这个就高高效了一点。但是不清楚 max的工作原理,不知道它的性能如何。

  心得:

  1、追求高效的翻页算法 —— 定位法。

declare @pageSize int --返回一页的记录数
declare @CurPage int --页号(第几页)0:第一页;-1最后一页。
declare @Count int
declare @id int
set @pageSize=10
set @CurPage =1
--定位
if @CurPage = -1
begin
--最后一页
set rowcount @pageSize
select @id=newsID from newsTemp order by newsID
end
if @CurPage > 0
begin
set @Count = @pageSize * (@CurPage -1) + 1
set rowcount @Count
select @id=newsID from newsTemp order by newsID desc
end

  --返回记录

set rowcount @pageSize
select * from newsTemp where newsID <=@id order by newsID descset rowcount 0

  思路:就是上面的算法的延续,就是说呢避免使用 not in 和 max 的方法。也就是这个思路:Select top 10 * from table1 where id>200,定位 —— 就是说要找到“临界点”,分页的临界点。找到了之后剩下的事情就好办了。

  缺点:单字段排序、排序字段的值不能重复(不是绝对不能重复,可以有少量的重复)。

  2、通用法 —— 颠颠倒倒法

  有的时候“定位法”的缺点是不可以接受的,但是没有关系,可以用这个的。

select * from table where id in
(
select top 10 ID from
(
select top 20 ID,addedDate from table
order by addedDate desc
) as aa order by addedDate
)
order by addedDate desc

  ID 是主键,addedDate 是排序字段。

  缺点:必须有主键。

下载本文
显示全文
专题