SQLServer2005分页存储过程

参考网络上多个例子之后,总结出适合自己的版本:

存储过程pro_PageList:

  1 /**
  2 数据分页存储过程
  3 配合类使用:\App_Code\PageList.cs
  4 ======================================
  5 ▲支持 联表、left/right/inner join
  6 ▲支持 select top n
  7 ▲支持 group by
  8 ▲不支持 select distinct ————请使用group by代替distinct
  9 */
 10 if exists (select 1
 11           from sysobjects
 12           where  id = object_id('dbo.pro_PageList')
 13           and type in ('P','PC'))
 14    drop procedure dbo.pro_PageList
 15 go
 16 
 17 
 18 /**
 19 数据分页存储过程
 20 1.详细参数意义,请参考类/App_Code/PageList.cs,在这里只是简单备注
 21 2.不支持distinct,请使用group by代替distinct
 22 */
 23 create procedure dbo.pro_PageList (
 24     @strTables varchar(max), --表名或视图名称
 25     @strFields varchar(max), --要显示的字段
 26     @strWhere varchar(max), --where条件
 27     @pageIndex int, --当页页码
 28     @pageSize int, --页码容量
 29     @strOrder varchar(255), --排序字段及规则
 30     @isGetCount int,  --是否计算记录总数(0:是  1:否[此时值为记录总数])
 31     @strGroupby varchar(255), --GROUP BY字段
 32     @strOrderWithoutPrefix varchar(255), --不带表名前缀的排序字段(a.name desc --> name desc);仅当@isGroupby=1时才有意义
 33     @recCount int output, --返回:记录总数
 34     @pageCount int output, --返回:总页数
 35     @exeSql varchar(max) output, --返回:当前页面执行的sql
 36     @allSql varchar(max) output --返回:不加分页查询的sql
 37 ) as
 38 begin 
 39     declare @countSql nvarchar(max)
 40     declare @isGroupby int --是否Group by (0:否  1:是);带有group by的查询及计算count的方式有很大不同,所以必须指定是否Group by,以节省性能开销
 41     set nocount on;
 42 
 43     --查询的字段
 44     if @strFields is null or @strFields = ''
 45             set @strFields='*'
 46 
 47     --查询的条件
 48     if @strWhere is null or @strWhere=''
 49             set @strWhere=''
 50     else
 51             set @strWhere=' WHERE ' + @strWhere
 52                 
 53     --GROUP BY
 54     if @strGroupby is null or @strGroupby=''
 55             begin
 56             set @strGroupby=''
 57                 set @isGroupby = 0
 58             end
 59     else
 60             begin
 61             set @strGroupby=' GROUP BY ' + @strGroupby
 62                 set @isGroupby = 1
 63             end
 64         
 65         --查询所有数据的sql
 66         if(@isGroupby = 0) --带有Group by
 67             begin
 68                 --注:这一行不要轻易改动,因为PageList.cs中有使用正则删除PageList__RowNum
 69                 set @allSql = 'SELECT ' + @strFields + ',ROW_NUMBER() OVER(ORDER BY ' + @strOrder + ') AS PageList__RowNum FROM ' + @strTables + @strWhere + @strGroupby
 70             end
 71         else --带有group by的查询及计算count的方式有很大不同,所以分开写
 72             begin
 73                 --注:这一行不要轻易改动,因为PageList.cs中有使用正则删除PageList__RowNum
 74                 set @allSql = 'SELECT ' + @strFields + ' FROM ' + @strTables + @strWhere + @strGroupby
 75                 set @allSql = 'SELECT *,ROW_NUMBER() OVER(ORDER BY ' + @strOrderWithoutPrefix + ') AS PageList__RowNum FROM ('+ @allSql +') AS __tmpTable'
 76             end
 77         
 78         --查询数据集的sql
 79         set @exeSql=' SELECT * FROM ( '+ @allSql + ') AS Dwhere WHERE PageList__RowNum BETWEEN ' + CAST(((@pageIndex-1)*@pageSize + 1) as nvarchar(20)) + ' AND ' + cast((@pageIndex*@pageSize) as nvarchar(20))
 80                 
 81         --执行查询
 82     exec (@exeSql)
 83 
 84     --计算记录数
 85     if(@isGetCount = 0)
 86         begin
 87                 if(@isGroupby = 0) --带有Group by
 88                     set @countSql='SELECT @recCount=COUNT(*) FROM ' + @strTables + @strWhere + @strGroupby
 89                 else --带有group by的查询及计算count的方式有很大不同,所以分开写
 90                     set @countSql='SELECT @recCount=COUNT(*) FROM (
 91                                        SELECT COUNT(*) AS iCount FROM ' + @strTables + @strWhere + @strGroupby +'
 92                                    ) AS __tmpTable'
 93                 --计算
 94             exec sp_executesql @countSql, N'@recCount INT OUT ',@recCount output
 95         end
 96     else
 97         begin
 98             set @recCount = @isGetCount
 99         end
100 
101     --计算分页总数
102     SET @pageCount=(@recCount + @pageSize - 1) / @pageSize
103 
104     --返回
105     select @recCount as recCount
106     select @pageCount as pageCount
107     select @exeSql as exeSql
108     select @allSql as allSql
109 
110     set nocount off;
111 end
112 go

 

调用类PageList.cs:

  1 using System;
  2 using System.Collections.Generic;
  3 using System.Data;
  4 using System.Linq;
  5 using System.Text.RegularExpressions;
  6 using System.Web;
  7 using XL.DB.DbOperaClass;
  8 
  9 /// <summary>
 10 /// 通用分页类
 11 /// </summary>
 12 public class PageList
 13 {
 14     /// <summary>
 15     /// 执行分页查询
 16     /// </summary>
 17     /// <param name="pageListData">输入、输出参数对象,具体参数说明请参考PageListData类</param>
 18     public static PageListData GetPageListData(ref PageListData pageListData)
 19     {
 20         #region 存储过程参数赋值
 21         DbParameterStruct[] para = null;
 22         para = new DbParameterStruct[13];
 23         para[0] = new DbParameterStruct();
 24         para[0].ParaName = "strTables";
 25         para[0].ParaValue = pageListData.strTables;
 26         para[1] = new DbParameterStruct();
 27         para[1].ParaName = "strFields";
 28         para[1].ParaValue = pageListData.strFields;
 29         para[2] = new DbParameterStruct();
 30         para[2].ParaName = "strWhere";
 31         para[2].ParaValue = pageListData.strWhere;
 32         para[3] = new DbParameterStruct();
 33         para[3].ParaName = "pageIndex";
 34         para[3].ParaValue = pageListData.pageIndex;
 35         para[4] = new DbParameterStruct();
 36         para[4].ParaName = "pageSize";
 37         para[4].ParaValue = pageListData.pageSize;
 38         para[5] = new DbParameterStruct();
 39         para[5].ParaName = "strOrder";
 40         para[5].ParaValue = pageListData.strOrder;
 41         para[6] = new DbParameterStruct();
 42         para[6].ParaName = "isGetCount";
 43         para[6].ParaValue = pageListData.isGetCount;
 44         para[7] = new DbParameterStruct();
 45         para[7].ParaName = "recCount";
 46         para[7].ParaValue = pageListData.recCount;
 47         para[8] = new DbParameterStruct();
 48         para[8].ParaName = "pageCount";
 49         para[8].ParaValue = pageListData.pageCount;
 50         para[9] = new DbParameterStruct();
 51         para[9].ParaName = "exeSql";
 52         para[9].ParaValue = pageListData.exeSql;
 53         para[10] = new DbParameterStruct();
 54         para[10].ParaName = "allSql";
 55         para[10].ParaValue = pageListData.allSql;
 56         para[11] = new DbParameterStruct();
 57         para[11].ParaName = "strGroupby";
 58         para[11].ParaValue = pageListData.strGroupby;
 59         para[12] = new DbParameterStruct();
 60         para[12].ParaName = "strOrderWithoutPrefix";
 61         para[12].ParaValue = pageListData.strOrderWithoutPrefix;
 62         #endregion
 63 
 64         DataSet dsResult = XL.WEB.PageBaseClass.DbPageBaseClass.DBConnOperaObj.ExecuteProcedureDs("pro_PageList", para);
 65         pageListData.dtResult = dsResult.Tables[0];
 66         pageListData.recCount = int.Parse(dsResult.Tables[1].Rows[0]["recCount"].ToString());
 67         pageListData.pageCount = int.Parse(dsResult.Tables[2].Rows[0]["pageCount"].ToString());
 68         pageListData.exeSql = dsResult.Tables[3].Rows[0]["exeSql"].ToString();
 69         pageListData.allSql = dsResult.Tables[4].Rows[0]["allSql"].ToString();
 70 
 71         return pageListData;
 72     }
 73 }
 74 
 75 /// <summary>
 76 /// 分页查询功能的 输入、输出参数
 77 /// </summary>
 78 public class PageListData
 79 {
 80     #region 定义变量 ————详细意义,请参下面公有变量的注释
 81     private string _strTables = "";//表名或视图名称
 82     private string _strFields = "*";//要显示的字段(默认为所有字段)
 83     private string _strWhere = "";//查询条件
 84 
 85     private int _pageIndex = 1;//当前第n页
 86     private int _pageSize = 30;//请求页面大小
 87 
 88     private string _strOrder = "";//排序字段及规则
 89     private int _isGetCount = 0;//是否计算记录总数(默认计算)
 90 
 91     private int _recCount = 0;//总行数
 92     private int _pageCount = 0;//总页数
 93 
 94     private string _exeSql = "";//当前页面执行的sql
 95     private string _allSql = "";//不加分页查询的sql(即返回所有数据的sql)
 96 
 97     private string _strGroupby = "";//Group by字段
 98     private string _strOrderWithoutPrefix = "";//不带表名前缀的排序字段(此参数值根据@strOrder自动生成)
 99 
100     private DataTable _dtResult = null;//当前页面的查询结果数据集
101     #endregion
102 
103     /// <summary>
104     /// [入参,必填]表名或视图名称
105     /// </summary>
106     /// <remarks>
107     /// 支持联表、left/right/inner join 等,例如:t_um_user a left join t_um_department b on (b.id=a.fid)
108     /// </remarks>
109     public string strTables
110     {
111         get { return _strTables; }
112         set { _strTables = value; }
113     }
114 
115     /// <summary>
116     /// [入参]字段名,默认为*
117     /// </summary>
118     public string strFields
119     {
120         get { return _strFields; }
121         set { _strFields = value; }
122     }
123 
124     /// <summary>
125     /// [入参]查询条件,不加where,无查询条件时可留空
126     /// </summary>
127     public string strWhere
128     {
129         get { return _strWhere; }
130         set { _strWhere = value; }
131     }
132 
133     /// <summary>
134     /// [入参]当前第几页
135     /// </summary>
136     public int pageIndex
137     {
138         get { return _pageIndex; }
139         set { _pageIndex = value; }
140     }
141 
142     /// <summary>
143     /// [入参]每页显示的记录数
144     /// </summary>
145     public int pageSize
146     {
147         get { return _pageSize; }
148         set { _pageSize = value; }
149     }
150 
151     /// <summary>
152     /// [入参,必填]排序字段及规则
153     /// </summary>
154     /// <remarks>
155     /// 不用加order by,例如:b.id asc,sum(a.id) desc
156     /// 如果有group by语句,则 排序字段必须出现在@strFields中(如果有别名,则排序字段必须使用别名)
157     /// </remarks>
158     public string strOrder
159     {
160         get { return _strOrder; }
161         set { _strOrder = value; }
162     }
163 
164     /// <summary>
165     /// [入参]是否计算记录总数
166     /// </summary>
167     /// <remarks>
168     ///     0:计算(默认)
169     /// 其它值:不计算,此时参数值代表记录总数,即@recCount直接返回该参数值
170     /// </remarks>
171     public int isGetCount
172     {
173         get { return _isGetCount; }
174         set { _isGetCount = value; }
175     }
176 
177     /// <summary>
178     /// [入参]Group by字段
179     /// </summary>
180     /// <remarks>
181     /// 不用加group by
182     /// 例如:b.id,a.id
183     /// 或者,再复杂一点:b.id,a.id having count(*)>1
184     /// </remarks>
185     public string strGroupby
186     {
187         get { return _strGroupby; }
188         set { _strGroupby = value; }
189     }
190 
191     /// <summary>
192     /// [入参]不带表名前缀的排序字段(a.name desc --> name desc)
193     /// </summary>
194     /// <remarks>
195     /// 仅当@strGroupby有值时才有意义
196     /// 排序字段必须出现在@strFields中(如果有别名,则排序字段必须使用别名)
197     /// 此参数值根据@strOrder自动生成
198     /// </remarks>
199     public string strOrderWithoutPrefix
200     {
201         get
202         {
203             //删除表名前缀(a.name desc --> name desc)
204             _strOrderWithoutPrefix = Regex.Replace(_strOrder, @"(\w)+\.", "");
205             return _strOrderWithoutPrefix;
206         }
207         set { _strOrderWithoutPrefix = value; }
208     }
209 
210     /****** 下面开始为返回参数 *****/
211 
212     /// <summary>
213     /// [返参]当前页面的查询结果数据集
214     /// </summary>
215     public DataTable dtResult
216     {
217         get
218         {
219             if (_dtResult.Columns.Contains("PageList__RowNum"))
220             {
221                 //删除ROW_NUMBER()生成的序号字段
222                 _dtResult.Columns.Remove("PageList__RowNum");
223             }
224             return _dtResult;
225         }
226         set { _dtResult = value; }
227     }
228 
229     /// <summary>
230     /// [返参]总记录数
231     /// </summary>
232     public int recCount
233     {
234         get { return _recCount; }
235         set { _recCount = value; }
236     }
237 
238     /// <summary>
239     /// [返参]总页数
240     /// </summary>
241     public int pageCount
242     {
243         get { return _pageCount; }
244         set { _pageCount = value; }
245     }
246 
247     /// <summary>
248     /// [返参]当前页面执行的sql
249     /// </summary>
250     /// <remarks>
251     /// 1.用于WebGrid批量修改功能中,仅限于单表查询
252     /// 2.自动在最后1列中插入序号列:PageList__RowNum
253     /// </remarks>
254     public string exeSql
255     {
256         get { return _exeSql; }
257         set { _exeSql = value; }
258     }
259 
260     /// <summary>
261     /// [返参]不加分页查询的sql(即返回所有数据的sql)
262     /// </summary>
263     /// <remarks>主要用于导出所有数据到excel中</remarks>
264     public string allSql
265     {
266         get 
267         {
268             //删除ROW_NUMBER()生成的序号字段
269             _allSql = Regex.Replace(_allSql, @",ROW_NUMBER\(\) OVER\(ORDER BY ([\s\S]*?)\) AS PageList__RowNum", "");
270             return _allSql;
271         }
272         set { _allSql = value; }
273     }
274 }

 

posted @ 2020-01-06 09:16  陈少鑫  阅读(218)  评论(0编辑  收藏  举报