2分法-通用存储过程分页

数据库
2分法-通用存储过程分页(top max模式)版本(性能相对之前的not in版本极大提高)

2分法-通用存储过程分页(top max模式)版本(性能相对之前的not in版本极大提高)

  1. --/*-----存储过程 分页处理 孙伟 2005-03-28创建 -------*/  
  2. --/*----- 对数据进行了2分处理使查询前半部分数据与查询后半部分数据性能相同 -------*/  
  3. --/*-----存储过程 分页处理 孙伟 2005-04-21修改 添加Distinct查询功能-------*/  
  4. --/*-----存储过程 分页处理 孙伟 2005-05-18修改 多字段排序规则问题-------*/  
  5. --/*-----存储过程 分页处理 孙伟 2005-06-15修改 多字段排序修改-------*/  
  6. --/*-----存储过程 分页处理 孙伟 2005-12-13修改 修改数据分页方式为top max模式 性能有极大提高-------*/  
  7. --/*-----缺点:相对之前的not in版本主键只能是整型字段,如主键为GUID类型请使用not in 模式的版本-------*/  
  8. CREATE PROCEDURE dbo.proc_ListPageInt  
  9. (  
  10. @tblName     nvarchar(200),        ----要显示的表或多个表的连接  
  11. @fldName     nvarchar(500) = '*',    ----要显示的字段列表  
  12. @pageSize    int = 10,        ----每页显示的记录个数  
  13. @page        int = 1,        ----要显示那一页的记录  
  14. @pageCount    int = 1 output,            ----查询结果分页后的总页数  
  15. @Counts    int = 1 output,                ----查询到的记录数  
  16. @fldSort    nvarchar(200) = null,    ----排序字段列表或条件  
  17. @Sort        bit = 0,        ----排序方法,0为升序,1为降序(如果是多字段排列Sort指代最后一个排序字段的排列顺序(最后一个排序字段不加排序标记)--程序传参如:' SortA Asc,SortB Desc,SortC ')  
  18. @strCondition    nvarchar(1000) = null,    ----查询条件,不需where  
  19. @ID        nvarchar(150),        ----主表的主键  
  20. @Dist                 bit = 0           ----是否添加查询字段的 DISTINCT 默认0不添加/1添加  
  21. )  
  22. AS  
  23. SET NOCOUNT ON  
  24. Declare @sqlTmp nvarchar(1000)        ----存放动态生成的SQL语句  
  25. Declare @strTmp nvarchar(1000)        ----存放取得查询结果总数的查询语句  
  26. Declare @strID     nvarchar(1000)        ----存放取得查询开头或结尾ID的查询语句  
  27.  
  28. Declare @strSortType nvarchar(10)    ----数据排序规则A  
  29. Declare @strFSortType nvarchar(10)    ----数据排序规则B  
  30.  
  31. Declare @SqlSelect nvarchar(50)         ----对含有DISTINCT的查询进行SQL构造  
  32. Declare @SqlCounts nvarchar(50)          ----对含有DISTINCT的总数查询进行SQL构造  
  33.  
  34.  
  35. if @Dist  = 0 
  36. begin  
  37.     set @SqlSelect = 'select ' 
  38.     set @SqlCounts = 'Count(*)' 
  39. end  
  40. else  
  41. begin  
  42.     set @SqlSelect = 'select distinct ' 
  43.     set @SqlCounts = 'Count(DISTINCT '+@ID+')'  
  44. end  
  45.  
  46.  
  47. if @Sort=0 
  48. begin  
  49.     set @strFSortType=' ASC ' 
  50.     set @strSortType=' DESC ' 
  51. end  
  52. else  
  53. begin  
  54.     set @strFSortType=' DESC ' 
  55.     set @strSortType=' ASC ' 
  56. end  
  57.  
  58.  
  59.  
  60. --------生成查询语句--------  
  61. --此处@strTmp为取得查询结果数量的语句  
  62. if @strCondition is null or @strCondition=''     --没有设置显示条件  
  63. begin  
  64.     set @sqlTmp =  @fldName + ' From ' + @tblName  
  65.     set @strTmp = @SqlSelect+' @Counts='+@SqlCounts+' FROM '+@tblName  
  66.     set @strID = ' From ' + @tblName  
  67. end  
  68. else  
  69. begin  
  70.     set @sqlTmp = + @fldName + 'From ' + @tblName + ' where (1>0) ' + @strCondition  
  71.     set @strTmp = @SqlSelect+' @Counts='+@SqlCounts+' FROM '+@tblName + ' where (1>0) ' + @strCondition  
  72.     set @strID = ' From ' + @tblName + ' where (1>0) ' + @strCondition  
  73. end  
  74.  
  75. ----取得查询结果总数量-----  
  76. exec sp_executesql @strTmp,N'@Counts int out ',@Counts out  
  77. declare @tmpCounts int  
  78. if @Counts = 0 
  79.     set @tmpCounts = 1 
  80. else  
  81.     set @tmpCounts = @Counts  
  82.  
  83.     --取得分页总数  
  84.     set @pageCount=(@tmpCounts+@pageSize-1)/@pageSize  
  85.  
  86.     /**//**当前页大于总页数 取最后一页**/  
  87.     if @page>@pageCount  
  88.         set @page=@pageCount  
  89.  
  90.     --/*-----数据分页2分处理-------*/  
  91.     declare @pageIndex int --总数/页大小  
  92.     declare @lastcount int --总数%页大小   
  93.  
  94.     set @pageIndex = @tmpCounts/@pageSize  
  95.     set @lastcount = @tmpCounts%@pageSize  
  96.     if @lastcount > 0  
  97.         set @pageIndex = @pageIndex + 1  
  98.     else  
  99.         set @lastcount = @pagesize  
  100.  
  101.     --//***显示分页  
  102.     if @strCondition is null or @strCondition=''     --没有设置显示条件  
  103.     begin  
  104.         if @pageIndex<2 or @page<=@pageIndex / 2 + @pageIndex % 2   --前半部分数据处理  
  105.             begin   
  106.                 if @page=1 
  107.                     set @strTmp=@SqlSelect+' top '+ CAST(@pageSize as VARCHAR(4))+' '+ @fldName+' from '+@tblName                          
  108.                         +' order by '+ @fldSort +' '+ @strFSortType  
  109.                 else  
  110.                 begin                      
  111.                     set @strTmp=@SqlSelect+' top '+ CAST(@pageSize as VARCHAR(4))+' '+ @fldName+' from '+@tblName  
  112.                         +' where '+@ID+' <(select min('+ @ID +') from ('+ @SqlSelect+' top '+ CAST(@pageSize*(@page-1) as Varchar(20)) +' '+ @ID +' from '+@tblName  
  113.                         +' order by '+ @fldSort +' '+ @strFSortType+') AS TBMinID)'  
  114.                         +' order by '+ @fldSort +' '+ @strFSortType  
  115.                 end      
  116.             end  
  117.         else  
  118.             begin  
  119.             set @page = @pageIndex-@page+1 --后半部分数据处理  
  120.                 if @page <= 1 --最后一页数据显示                  
  121.                     set @strTmp=@SqlSelect+' * from ('+@SqlSelect+' top '+ CAST(@lastcount as VARCHAR(4))+' '+ @fldName+' from '+@tblName  
  122.                         +' order by '+ @fldSort +' '+ @strSortType+') AS TempTB'+' order by '+ @fldSort +' '+ @strFSortType   
  123.                 else  
  124.                     set @strTmp=@SqlSelect+' * from ('+@SqlSelect+' top '+ CAST(@pageSize as VARCHAR(4))+' '+ @fldName+' from '+@tblName  
  125.                         +' where '+@ID+' >(select max('+ @ID +') from('+ @SqlSelect+' top '+ CAST(@pageSize*(@page-2)+@lastcount as Varchar(20)) +' '+ @ID +' from '+@tblName  
  126.                         +' order by '+ @fldSort +' '+ @strSortType+') AS TBMaxID)'  
  127.                         +' order by '+ @fldSort +' '+ @strSortType+') AS TempTB'+' order by '+ @fldSort +' '+ @strFSortType   
  128.             end  
  129.     end  
  130.  
  131.     else --有查询条件  
  132.     begin  
  133.         if @pageIndex<2 or @page<=@pageIndex / 2 + @pageIndex % 2   --前半部分数据处理  
  134.         begin  
  135.                 if @page=1 
  136.                     set @strTmp=@SqlSelect+' top '+ CAST(@pageSize as VARCHAR(4))+' '+ @fldName+' from '+@tblName                          
  137.                         +' where 11=1 ' + @strCondition + ' order by '+ @fldSort +' '+ @strFSortType  
  138.                 else  
  139.                 begin                      
  140.                     set @strTmp=@SqlSelect+' top '+ CAST(@pageSize as VARCHAR(4))+' '+ @fldName+' from '+@tblName  
  141.                         +' where '+@ID+' <(select min('+ @ID +') from ('+ @SqlSelect+' top '+ CAST(@pageSize*(@page-1) as Varchar(20)) +' '+ @ID +' from '+@tblName  
  142.                         +' where (11=1) ' + @strCondition +' order by '+ @fldSort +' '+ @strFSortType+') AS TBMinID)'  
  143.                         +' '+ @strCondition +' order by '+ @fldSort +' '+ @strFSortType  
  144.                 end              
  145.         end  
  146.         else  
  147.         begin   
  148.             set @page = @pageIndex-@page+1 --后半部分数据处理  
  149.             if @page <= 1 --最后一页数据显示  
  150.                     set @strTmp=@SqlSelect+' * from ('+@SqlSelect+' top '+ CAST(@lastcount as VARCHAR(4))+' '+ @fldName+' from '+@tblName  
  151.                         +' where (11=1) '+ @strCondition +' order by '+ @fldSort +' '+ @strSortType+') AS TempTB'+' order by '+ @fldSort +' '+ @strFSortType                       
  152.             else  
  153.                     set @strTmp=@SqlSelect+' * from ('+@SqlSelect+' top '+ CAST(@pageSize as VARCHAR(4))+' '+ @fldName+' from '+@tblName  
  154.                         +' where '+@ID+' >(select max('+ @ID +') from('+ @SqlSelect+' top '+ CAST(@pageSize*(@page-2)+@lastcount as Varchar(20)) +' '+ @ID +' from '+@tblName  
  155.                         +' where (11=1) '+ @strCondition +' order by '+ @fldSort +' '+ @strSortType+') AS TBMaxID)'  
  156.                         +' '+ @strCondition+' order by '+ @fldSort +' '+ @strSortType+') AS TempTB'+' order by '+ @fldSort +' '+ @strFSortType                  
  157.         end      
  158.     end  
  159.  
  160. ------返回查询结果-----  
  161. exec sp_executesql @strTmp  
  162. --print @strTmp  
  163. SET NOCOUNT OFF  
  164. GO 

 调用方法列子:
 

  1. /**//// <summary> 
  2.     /// 通用分页数据读取函数   
  3.     /// 注意:在函数调用外部打开和关闭连接,以及关闭数据读取器  
  4.     /// </summary> 
  5.     /// <param name="comm">SqlCommand对象</param> 
  6.     /// <param name="_tblName">查询的表/表联合</param> 
  7.     /// <param name="_fldName">要查询的字段名</param> 
  8.     /// <param name="_pageSize">每页数据大小</param> 
  9.     /// <param name="_page">当前第几页</param> 
  10.     /// <param name="_fldSort">排序字段</param> 
  11.     /// <param name="_Sort">排序顺序0降序1升序</param> 
  12.     /// <param name="_strCondition">过滤条件</param> 
  13.     /// <param name="_ID">主表主键</param>          
  14.     /// <param name="_dr">返回的SqlDataReader ref</param> 
  15.     public static void CutPageData(SqlConnection conn, ref SqlCommand comm, string _tblName, string _fldName, int _pageSize, int _page, string _fldSort, int _Sort, string _strCondition, string _ID, ref SqlDataReader _dr)  
  16.     {  
  17.         //注意:在函数调用外部打开和关闭连接,以及关闭数据读取器  
  18.         //comm = new SqlCommand("proc_ListPage",conn);  
  19.         //comm.CommandType = CommandType.StoredProcedure;  
  20.         comm.Parameters.Add("@tblName", SqlDbType.NVarChar, 200);  
  21.         comm.Parameters["@tblName"].Value = _tblName;  
  22.         comm.Parameters.Add("@fldName", SqlDbType.NVarChar, 500);  
  23.         comm.Parameters["@fldName"].Value = _fldName;  
  24.         comm.Parameters.Add("@pageSize", SqlDbType.Int);  
  25.         comm.Parameters["@pageSize"].Value = _pageSize;  
  26.         comm.Parameters.Add("@page", SqlDbType.Int);  
  27.         comm.Parameters["@page"].Value = _page;  
  28.         comm.Parameters.Add("@fldSort", SqlDbType.NVarChar, 200);  
  29.         comm.Parameters["@fldSort"].Value = _fldSort;  
  30.         comm.Parameters.Add("@Sort", SqlDbType.Bit);  
  31.         comm.Parameters["@Sort"].Value = _Sort;  
  32.         comm.Parameters.Add("@strCondition", SqlDbType.NVarChar, 1000);  
  33.         comm.Parameters["@strCondition"].Value = _strCondition;  
  34.         comm.Parameters.Add("@ID", SqlDbType.NVarChar, 150);  
  35.         comm.Parameters["@ID"].Value = _ID;  
  36.         comm.Parameters.Add("@Counts", SqlDbType.Int, 0);  
  37.         comm.Parameters["@Counts"].Direction = ParameterDirection.Output;  
  38.         comm.Parameters.Add("@pageCount", SqlDbType.Int, 0);  
  39.         comm.Parameters["@pageCount"].Direction = ParameterDirection.Output;  
  40.  
  41.         _dr = comm.ExecuteReader();  
  42.     }  

调用例如:

CutPageData(conn, ref comm, "VOX_CDSinger", "id, cdsinger, cdsingertype, area, cdsingerreadme", 15, page, "id", 1, strFilter, "id", ref dr);
对应说明:

CutPageData(数据连接对象, ref Sqlcommand对象, "需要表或视图名称", "要查询的字段", 每页读取数据条数, 当前页, "排序字段可多字段如(addtime desc, visitcounts注意这里最后一个字段不加desc或asc 最后一个字段对应于后面的排序规则)", 排序方式(1 desc 0 asc), where条件(这里不再添加where条件添加如:' and visitcounts>100'), 表主键, ref 返回的SqlDataReader对象);

这里的调用同样适用于之前的not in版本.

编者注:这篇文章是为了另一篇文章做准备之用,故小编在这个就不多做推荐其他文章了。

责任编辑:艾婧 来源: 博客园
相关推荐

2010-06-10 12:37:27

MySQL分页查询

2010-06-11 14:41:20

MySQL分页查询

2011-03-24 14:15:27

双TOP二分法分页

2010-05-13 15:54:56

MySQL分页查询

2015-08-19 14:18:56

SQLasp.net后台调用

2011-04-15 13:21:41

DB2翻页存储

2010-09-13 13:12:28

sqlserver分页

2010-11-29 09:45:30

Sybase分页

2023-12-27 23:30:50

2011-03-28 10:46:36

sql server存储分页

2011-03-24 13:38:47

SQL Server 存储分页

2010-11-29 09:12:46

sybase分页存储过

2011-10-10 16:44:37

分页数据库

2021-12-26 00:10:39

二分法排查版本

2010-10-26 14:50:11

oracle存储过程

2010-09-14 10:47:45

sql server存

2012-04-23 15:10:18

ASP.NET

2011-06-17 17:37:16

JavaSQL Server

2018-06-15 14:26:42

2021-10-19 09:59:25

二分法排序数组
点赞
收藏

51CTO技术栈公众号