SQL 儲存過程 分頁

2021-04-13 09:29:04 字數 3056 閱讀 6058

1.「俄羅斯儲存過程」的改良版

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

endset 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

endif @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 desc

set 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 是排序字段。

缺點:必須有主鍵。

sql 儲存過程分頁

create proc myx prpagerecordset querystr nvarchar 1000 keyfield nvarchar 200 pagesize int,pagenumber int as begin declare sqltext as nvarchar 4000 dec...

SQL 分頁儲存過程

create procedure splitpage sql nvarchar 4000 不帶排序語句的sql語句 page int,頁碼 recsperpage int,每頁容納的記錄數 id varchar 255 需要排序的不重複的id號 sort varchar 255 排序欄位及規則 as...

SQL分頁儲存過程

create procedure prcpager 獲得某一頁的資料 currpage int 1,當前頁頁碼 即top currpage showcolumn varchar 2000 需要得到的字段 即 column1,column2,tabname varchar 2000 需要檢視的表名 即...