二分法使用select max大量数据分页

来源:互联网 发布:odum面积计算法 编辑:程序博客网 时间:2024/05/03 00:27
    最近发现,这个分页方法有一个重大缺陷,就是要求作为主见的 ID 字段,和你要排序的字段的顺序必须对应,否则不能工作。
    1. --/*-----存储过程 分页处理 孙伟 2005-03-28创建 ------*/ 
    2. --/*-----存储过程 分页处理 浪尘 2008-9-1修改----------*/
    3. --/*----- 苗苗老师 2009-11-08 修改 --------------------*/
    4. --/*----- 对数据进行了2分处理使查询前半部分数据与查询后半部分数据性能相同 -------*/ 
    5. alter PROCEDURE proc_paged_2part_selectMax 
    6. @tblName     nvarchar(200),        ----要显示的表或多个表的连接 
    7. @fldName     nvarchar(500) = '*',    ----要显示的字段列表 
    8. @pageSize    int = 10,        ----每页显示的记录个数 
    9. @page        int = 1,        ----要显示那一页的记录 
    10. @fldSort    nvarchar(200) = null,    ----排序字段列表或条件 
    11. @Sort        bit = 0,        ----排序方法,0为升序,1为降序(如果是多字段排列Sort指代最后一个排序字段的排列顺序(最后一个排序字段不加排序标记)--程序传参如:' SortA Asc,SortB Desc,SortC '
    12. @strCondition    nvarchar(1000) = null,    ----查询条件,不需where 
    13. @ID        nvarchar(150),        ----主表的主键 
    14. @Dist                 bit = 0,           ----是否添加查询字段的 DISTINCT 默认0不添加/1添加 
    15. @pageCount    int = 1 output,            ----查询结果分页后的总页数 
    16. @Counts    int = 1 output                ----查询到的记录数 
    17. AS 
    18. SET NOCOUNT ON 
    19. Declare @sqlTmp nvarchar(1000)        ----存放动态生成的SQL语句 
    20. Declare @strTmp nvarchar(1000)        ----存放取得查询结果总数的查询语句 
    21. Declare @strID     nvarchar(1000)        ----存放取得查询开头或结尾ID的查询语句 
    22. Declare @strSortType nvarchar(10)    ----数据排序规则A 
    23. Declare @strFSortType nvarchar(10)    ----数据排序规则B 
    24. Declare @SqlSelect nvarchar(50)         ----对含有DISTINCT的查询进行SQL构造 
    25. Declare @SqlCounts nvarchar(50)          ----对含有DISTINCT的总数查询进行SQL构造 
    26. declare @timediff datetime  --耗时测试时间差 
    27. select @timediff=getdate() 
    28. if @Dist  = 0 
    29. begin 
    30.     set @SqlSelect = 'select ' 
    31.     set @SqlCounts = 'Count(*)' 
    32. end 
    33. else 
    34. begin 
    35.     set @SqlSelect = 'select distinct ' 
    36.     set @SqlCounts = 'Count(DISTINCT '+@ID+')' 
    37. end 
    38. if @Sort=0 
    39. begin 
    40.     set @strFSortType=' ASC ' 
    41.     set @strSortType=' DESC ' 
    42. end 
    43. else 
    44. begin 
    45.     set @strFSortType=' DESC ' 
    46.     set @strSortType=' ASC ' 
    47. end 
    48. --------生成查询语句-------- 
    49. --此处@strTmp为取得查询结果数量的语句 
    50. if @strCondition is null or @strCondition=''     --没有设置显示条件 
    51. begin 
    52.     set @sqlTmp = @fldName + ' From ' + @tblName 
    53.     set @strTmp = @SqlSelect+' @Counts='+@SqlCounts+' FROM '+@tblName 
    54.     set @strID = ' From ' + @tblName 
    55. end 
    56. else 
    57. begin 
    58.     set @sqlTmp = @fldName + 'From ' + @tblName + ' where (1>0) ' + @strCondition 
    59.     set @strTmp = @SqlSelect+' @Counts='+@SqlCounts+' FROM '+@tblName + ' where (1>0) ' + @strCondition 
    60.     set @strID = ' From ' + @tblName + ' where (1>0) ' + @strCondition 
    61. end 
    62. ----取得查询结果总数量----- 
    63. exec sp_executesql @strTmp,N'@Counts int out ',@Counts out 
    64. declare @tmpCounts int 
    65. if @Counts = 0 
    66.     set @tmpCounts = 1 
    67. else 
    68.     set @tmpCounts = @Counts 
    69.     --取得分页总数 
    70.     set @pageCount=(@tmpCounts+@pageSize-1)/@pageSize 
    71.     /**//**//**//**当前页大于总页数 取最后一页**/ 
    72.     if @page>@pageCount 
    73.         set @page=@pageCount 
    74.     --/*-----数据分页2分处理-------*/ 
    75.     declare @pageIndex int --总数/页大小 
    76.     declare @lastcount int --总数%页大小  
    77.     set @pageIndex = @tmpCounts/@pageSize 
    78.     set @lastcount = @tmpCounts%@pageSize 
    79.     if @lastcount > 0 
    80.         set @pageIndex = @pageIndex + 1 
    81.     else 
    82.         set @lastcount = @pagesize 
    83.     --//***显示分页 
    84.     if @strCondition is null or @strCondition=''     --没有设置显示条件 
    85.     begin 
    86.         if @pageIndex<2 or @page<=@pageIndex / 2 + @pageIndex % 2   --前半部分数据处理 
    87.             begin  
    88.                 if @page=1 
    89.                     set @strTmp=@SqlSelect+' top '+ CAST(@pageSize as VARCHAR(4))+' '+ @fldName+' from '+@tblName                         
    90.                         +' order by '+ @fldSort +' '+ @strFSortType 
    91.                 else 
    92.                 begin 
    93.                     if @Sort=1 
    94.                     begin                     
    95.                     set @strTmp=@SqlSelect+' top '+ CAST(@pageSize as VARCHAR(4))+' '+ @fldName+' from '+@tblName 
    96.                         +' where '+@ID+' <(select min('+ @ID +') from ('+ @SqlSelect+' top '+ CAST(@pageSize*(@page-1) as Varchar(20)) +' '+ @ID +' from '+@tblName 
    97.                         +' order by '+ @fldSort +' '+ @strFSortType+') AS TBMinID)' 
    98.                         +' order by '+ @fldSort +' '+ @strFSortType 
    99.                     end 
    100.                     else 
    101.                     begin 
    102.                     set @strTmp=@SqlSelect+' top '+ CAST(@pageSize as VARCHAR(4))+' '+ @fldName+' from '+@tblName 
    103.                         +' where '+@ID+' >(select max('+ @ID +') from ('+ @SqlSelect+' top '+ CAST(@pageSize*(@page-1) as Varchar(20)) +' '+ @ID +' from '+@tblName 
    104.                         +' order by '+ @fldSort +' '+ @strFSortType+') AS TBMinID)' 
    105.                         +' order by '+ @fldSort +' '+ @strFSortType  
    106.                     end 
    107.                 end     
    108.             end 
    109.         else 
    110.             begin 
    111.             set @page = @pageIndex-@page+1 --后半部分数据处理 
    112.                 if @page <= 1 --最后一页数据显示                 
    113.                     set @strTmp=@SqlSelect+' * from ('+@SqlSelect+' top '+ CAST(@lastcount as VARCHAR(4))+' '+ @fldName+' from '+@tblName 
    114.                         +' order by '+ @fldSort +' '+ @strSortType+') AS TempTB'+' order by '+ @fldSort +' '+ @strFSortType  
    115.                 else 
    116.                     if @Sort=1 
    117.                     begin 
    118.                     set @strTmp=@SqlSelect+' * from ('+@SqlSelect+' top '+ CAST(@pageSize as VARCHAR(4))+' '+ @fldName+' from '+@tblName 
    119.                         +' where '+@ID+' >(select max('+ @ID +') from('+ @SqlSelect+' top '+ CAST(@pageSize*(@page-2)+@lastcount as Varchar(20)) +' '+ @ID +' from '+@tblName 
    120.                         +' order by '+ @fldSort +' '+ @strSortType+') AS TBMaxID)' 
    121.                         +' order by '+ @fldSort +' '+ @strSortType+') AS TempTB'+' order by '+ @fldSort +' '+ @strFSortType 
    122.                     end 
    123.                     else 
    124.                     begin 
    125.                     set @strTmp=@SqlSelect+' * from ('+@SqlSelect+' top '+ CAST(@pageSize as VARCHAR(4))+' '+ @fldName+' from '+@tblName 
    126.                         +' where '+@ID+' <(select min('+ @ID +') from('+ @SqlSelect+' top '+ CAST(@pageSize*(@page-2)+@lastcount as Varchar(20)) +' '+ @ID +' from '+@tblName 
    127.                         +' order by '+ @fldSort +' '+ @strSortType+') AS TBMaxID)' 
    128.                         +' order by '+ @fldSort +' '+ @strSortType+') AS TempTB'+' order by '+ @fldSort +' '+ @strFSortType  
    129.                     end 
    130.             end 
    131.     end 
    132.     else --有查询条件 
    133.     begin 
    134.         if @pageIndex<2 or @page<=@pageIndex / 2 + @pageIndex % 2   --前半部分数据处理 
    135.         begin 
    136.                 if @page=1 
    137.                     set @strTmp=@SqlSelect+' top '+ CAST(@pageSize as VARCHAR(4))+' '+ @fldName+' from '+@tblName                         
    138.                         +' where 1=1 ' + @strCondition + ' order by '+ @fldSort +' '+ @strFSortType 
    139.                 else if(@Sort=1) 
    140.                 begin                     
    141.                     set @strTmp=@SqlSelect+' top '+ CAST(@pageSize as VARCHAR(4))+' '+ @fldName+' from '+@tblName 
    142.                         +' where '+@ID+' <(select min('+ @ID +') from ('+ @SqlSelect+' top '+ CAST(@pageSize*(@page-1) as Varchar(20)) +' '+ @ID +' from '+@tblName 
    143.                         +' where (1=1) ' + @strCondition +' order by '+ @fldSort +' '+ @strFSortType+') AS TBMinID)' 
    144.                         +' '+ @strCondition +' order by '+ @fldSort +' '+ @strFSortType 
    145.                 end 
    146.                 else 
    147.                 begin 
    148.                     set @strTmp=@SqlSelect+' top '+ CAST(@pageSize as VARCHAR(4))+' '+ @fldName+' from '+@tblName 
    149.                         +' where '+@ID+' >(select max('+ @ID +') from ('+ @SqlSelect+' top '+ CAST(@pageSize*(@page-1) as Varchar(20)) +' '+ @ID +' from '+@tblName 
    150.                         +' where (1=1) ' + @strCondition +' order by '+ @fldSort +' '+ @strFSortType+') AS TBMinID)' 
    151.                         +' '+ @strCondition +' order by '+ @fldSort +' '+ @strFSortType  
    152.                 end            
    153.         end 
    154.         else 
    155.         begin  
    156.             set @page = @pageIndex-@page+1 --后半部分数据处理 
    157.             if @page <= 1 --最后一页数据显示 
    158.                     set @strTmp=@SqlSelect+' * from ('+@SqlSelect+' top '+ CAST(@lastcount as VARCHAR(4))+' '+ @fldName+' from '+@tblName 
    159.                         +' where (1=1) '+ @strCondition +' order by '+ @fldSort +' '+ @strSortType+') AS TempTB'+' order by '+ @fldSort +' '+ @strFSortType                      
    160.             else if(@Sort=1) 
    161.                     set @strTmp=@SqlSelect+' * from ('+@SqlSelect+' top '+ CAST(@pageSize as VARCHAR(4))+' '+ @fldName+' from '+@tblName 
    162.                         +' where '+@ID+' >(select max('+ @ID +') from('+ @SqlSelect+' top '+ CAST(@pageSize*(@page-2)+@lastcount as Varchar(20)) +' '+ @ID +' from '+@tblName 
    163.                         +' where (1=1) '+ @strCondition +' order by '+ @fldSort +' '+ @strSortType+') AS TBMaxID)' 
    164.                         +' '+ @strCondition+' order by '+ @fldSort +' '+ @strSortType+') AS TempTB'+' order by '+ @fldSort +' '+ @strFSortType     
    165.             else 
    166.                     set @strTmp=@SqlSelect+' * from ('+@SqlSelect+' top '+ CAST(@pageSize as VARCHAR(4))+' '+ @fldName+' from '+@tblName 
    167.                         +' where '+@ID+' <(select min('+ @ID +') from('+ @SqlSelect+' top '+ CAST(@pageSize*(@page-2)+@lastcount as Varchar(20)) +' '+ @ID +' from '+@tblName 
    168.                         +' where (1=1) '+ @strCondition +' order by '+ @fldSort +' '+ @strSortType+') AS TBMaxID)' 
    169.                         +' '+ @strCondition+' order by '+ @fldSort +' '+ @strSortType+') AS TempTB'+' order by '+ @fldSort +' '+ @strFSortType             
    170.         end     
    171.     end 
    172. ------返回查询结果----- 
    173. exec sp_executesql @strTmp 
    174. select datediff(ms,@timediff,getdate()) as 耗时 
    175. --print @strTmp 
    176. SET NOCOUNT OFF 
    177. GO