看了很多海量資料分頁,大都都是單錶的,而且當資料增大時效率下降但是排序的列不能有重複值,而在sql 2005 裡通過 over子句可以解決,不過它也只是在後台把查詢結果加一列,然後所有資料查一遍,每條記錄插入序號,當有上千萬資料時效率也是有點低的。
所以我歸納了下,如果排序的列有重複,就用sql2005 的儲存過程,否則用我寫的儲存過程
sql 2005的儲存過程:
create procedure [dbo].[sp_common_pagechange]
@sql nvarchar(4000), --sql字串
@orderstring nvarchar(100),
@pageindex int,
@pagesize int,
@recordcount int out,
@pagecount int out
as /*計算頁面資料*/
declare @pageindex1 int
declare @sqlrecordcount nvarchar(4000)
set @pageindex1=@pageindex+1;
set @sqlrecordcount ='select @recordcount=count(*) from ('+@sql+') mxf'
/*獲取記錄數*/
exec sp_executesql @sqlrecordcount,n'@recordcount int output',@recordcount output--計算總頁數
set @pagecount = ceiling(@recordcount * 1.0 / @pagesize)
set @sql='('+@sql+') h'
/* 基於sql server 2005 */
set @sql=n'select serialnumber,* from (select *,row_number() over (order by '+@orderstring+')'
+'as serialnumber from '+@sql+') as t where t.serialnumber > ( '+convert(nvarchar(100),@pageindex)+' * '+ convert(nvarchar(100),@pagesize)+' ) and'
+' t.serialnumber <= ( '+convert(nvarchar(100),@pageindex1)+' * '+convert(nvarchar(100),@pagesize)+' )'
exec (@sql)
本人寫的儲存過程:
由於比通用的改進了一些,所以要複雜些。。
set ansi_nulls on
set quoted_identifier on
go if rtrim(ltrim(@ordervalue)) = '' --傳統分頁
begin
-- -- 去掉前面的表
-- declare @tmporderfield varchar(255)
-- set @tmporderfield = @orderfield
-- set @tmporderfield = reverse(@tmporderfield);
-- set @tmporderfield = substring(@tmporderfield,0,charindex('.',@tmporderfield))
-- set @tmporderfield = reverse(@tmporderfield);
if @ordertype !=0
begin
set @strtemp= '>(select max(' + ' ' +@orderfield+ ') from (select top '
+str((@pageindex-1)*@pagesize) + ' '+@orderfield +' from '+@tbnames
+ @strwheresql+ ' '+ @strorder +') as tb)'
end
else
begin
set @strtemp= ' <(select min('+ ' ' +@orderfield+ ') from (select top '
+str((@pageindex-1)*@pagesize) + ' '+@orderfield +' from '+@tbnames
+ @strwheresql+ ' '+ @strorder +') as tb)'
end
end
else
begin -- 根據 提供的比較值
declare @oper char(3)
set @oper = ''
if @pagedirection = 1
begin
if @ordertype != 0 -- desc 降序
begin
set @oper = ' > '
end
else
set @oper = ' < '
end
else
begin
if @ordertype !=0 -- desc 降序
begin
set @oper = ' < '
set @strorderin = 'order by ' + @orderfield + ' desc '
end
else
begin
set @oper = ' > '
set @strorderin = 'order by ' + @orderfield + ' asc '
end
end;
if @orderfieldtype = 's'
begin
set @strtemp= @oper + +''''+ @ordervalue +'''';
end
else
set @strtemp= @oper + @ordervalue--cast(@ordervalue as int);
end
--------------分頁為第一頁------------
if @pageindex =1 or @pageindex =0
begin
set @pageindex =1
set @strsql = 'select top ' +str(@pagesize)+ ' ' + @tbfields + ' from '+ @tbnames + @strwheresql+ ' ' + @strorder
end
else if @pageindex = -1 --最後一頁
begin
if @ordertype !=0
begin
set @strorderin='order by ' + @orderfield + ' desc '
end
else
begin
set @strorderin='order by '+ @orderfield + ' asc'
end
set @strsql = 'select top ' +str(@pagesize)+ ' ' + @tbfields + ' from '+ @tbnames + @strwheresql + ' ' + @strorderin
set @strsql = 'select * from (' + @strsql + ' ) t '+ @strorder;
end
else
begin
declare @temp varchar(200)
set @temp = ''
if rtrim(ltrim(@strwhere)) != ''
set @temp = ' and ' + @strwhere
if if rtrim(ltrim(@ordervalue)) = ''
set @strsql = 'select top ' +str(@pagesize) + ' ' + @tbfields
+' from ' + @tbnames + ' where '+@orderfield +' '
+ @strtemp + ' ' + @temp + @strorder
else
begin
set @strsql = 'select top ' +str(@pagesize) + ' ' + @tbfields
+' from ' + @tbnames + ' where '+@orderfield +' '
+ @strtemp + ' ' + @temp + @strorderin
set @strsql = 'select * from(' + @strsql + ') tb ' + @strorder
end
end
exec sp_executesql @strsqlcount,n'@totalcout int output',@total output
exec(@strsql)
@ordervalue varchar(20) = '', --排序欄位上一次頁最大或最小值
當 @ordervalue 不為空時,查詢900到1000的資料 不用查詢前900條,直接根據這個@ordervalue值就可以了。
我認為分頁儲存過程只應該有乙個通用的寫法.
有唯一排序字段,該怎麼寫/沒有唯一排序字段,該怎麼寫. 類似這樣
我:還沒有細看
海量資料分頁
language vbscript codepage 936 分頁sql語句生成 function getpagesql tblname,fldname,pagesize,pageindex,ordertype,strwhere dim strtemp,strsql,strorder 根據排序方式生...
海量資料的分頁
第一種方法 declare pagesize int,currpage int,topnum int,previous int select pagesize 30 select currpage 2 select topnum currpage pagesize select previous c...
海量資料分頁查詢
select top 25 id,registerid,filenameid,createtime from tbfilenamerecord where id select min id from select top 100 id from tbfilenamerecord where regi...