一、接上文,使用的是jquery AJAX 进行分页
分页存储过程代码如下:
ALTER PROCEDURE [dbo].[USP_GetAlbumByPage] @pageIndex int,--当前页 @pageSize int,--页容量 @totalCount int out--数据的总条数 AS BEGIN --定义开始和结束的下标 Declare @startIndex int,@endIndex int set @startIndex = (@pageIndex - 1 )*@pageSize + 1 set @endIndex = @pageIndex * @pageSize --执行sql语句 select * from (select *,ROW_NUMBER() over(order by Paid)as row from BlogPhotoAlblum where PaIsDel=0) as t where t.row>[email protected] and t.row<=@endIndex --给输出参数赋值 select @totalCount = COUNT(*)from BlogPhotoAlblum where PaIsDel=0 END
那么在DAL层如何调用这个存储过程了?
在DAL层执行的代码如下:需要返回list集合才方便序列化为Json对象,
a)如果参数中含有out 参数或者是构造函数的返回值,需要注意输出第三个参数的类型,
b)注意调用的方法为 RunProcedure
public List<BlogPhotoAlblum> GetAlblumByPage(int pageIndex, int pageSize, out int totalCount) { totalCount = 0; SqlParameter[] parameters = { new SqlParameter("@pageIndex", pageIndex), new SqlParameter("@pageSize", pageSize), new SqlParameter("@totalCount",totalCount ) }; //设置第三个参数的类型 parameters[2].Direction = System.Data.ParameterDirection.Output; DataTable dt = DbHelperSQL.RunProcedure("[USP_GetAlbumByPage]", parameters, "de").Tables[0]; //给第三个参数赋值 totalCount = Convert.ToInt32(parameters[2].Value); //DataSet s = new DataSet(); //DataTable dt = new DataTable(); //dt.DefaultView.Table.DefaultView.Table //将dt转成List集合,这里很关键,因为json对象返回的值的对象不能循环 //创建一个集合对象 List<BlogPhotoAlblum> list = new List<BlogPhotoAlblum>(); foreach (DataRow row in dt.Rows) { if (row != null) { //this既可以调用自己的方法,也可以调用父类的方法 //base只能调用父类的方法 BlogPhotoAlblum model = this.DataRowToModel(row); list.Add(model); } } return list; }
二、使用 AspNetPager 分页控件
前端除了使用JQuery插件实现分页外,还可使用使用 AspNetPager 分页控件。
要使用 AspNetPager 分页控件,必须最少指定它的 RecordCount 属性的值,另外如果需要,指定并编写 PageChanging 或 PageChanged 事件的处理程序,可以在PageChanging事件处理程序中取消分页事件,在PageChanged事件处理程序中绑定数据或实现自定义的数据呈现逻辑。 RecordCount 属性指定要分页的所有数据的总项数,若未指定该值或该值小于等于 PageSize ,即要分页的数据只有一页,则AspNetPager控件默认会自动隐藏而不显示任何内容,若需在只有一页数据的情况下显示AspNetPager分页控件,可以将它的AlwaysShow属性设为true即可。
示例如下:
<form id="form1" runat="server"> <asp:Repeater ID="Repeater1" runat="server" OnItemCommand="Repeater1_ItemCommand"> <ItemTemplate> <div class="albDiv"> <ul> <li> <img src="/upload/img/<%#Eval("PSrc") %>" /> </li> <li><%#Eval("PTitle") %></li> <li> <asp:LinkButton CommandName="Del" CommandArgument=‘<%#Eval("PId") %>‘ ID="LinkButton1" runat="server">删除</asp:LinkButton> | <a href="/0906/Edit.aspx?id=<%#Eval("PId") %>&albId=<%#Eval("PAlbum") %>">修改</a> | <a href="/0906/Update.aspx?id=<%#Eval("PId") %>&albId=<%#Eval("PAlbum") %>">上传图片</a> </li> </ul> </div> </ItemTemplate> </asp:Repeater> </form>
后台cs代码:
protected void Page_Load(object sender, EventArgs e) { BindData(); } private void BindData() { //得到一些数据 //获取或设置分页控件的当前页的索引 int pageIndex = this.AspNetPager1.CurrentPageIndex; //获取或设置每页显示的项数 int pageSize = this.AspNetPager1.PageSize; int totalCount = 0; List<BlogPhoto> list = bll.GetBlogPhotoList(int.Parse(albId), pageIndex, pageSize, out totalCount); //一定要指定 RecordCount属性,记录总页数 this.AspNetPager1.RecordCount = totalCount; //绑定数据,前台界面中的<%#Eval("PId") %> 的数据源就是在这里获得的 Repeater1.DataSource = list; Repeater1.DataBind(); } protected void AspNetPager1_PageChanging(object src, Wuqi.Webdiyer.PageChangingEventArgs e) { //NewPageIndex 获取用户在 AspNetPager 控件的页选择元素中选定的或在页索引文本框中手工输入的页的索引。 int pageIndex = e.NewPageIndex; //从e中获取最新的当前页面 this.AspNetPager1.CurrentPageIndex = pageIndex; //从新绑定一下 BindData(); }
分页存储过程代码如下:
ALTER PROCEDURE [dbo].[USP_GetAlbumByPage] @pageIndex int,--当前页 @pageSize int,--页容量 @totalCount int out--数据的总条数 AS BEGIN --定义开始和结束的下标 Declare @startIndex int,@endIndex int set @startIndex = (@pageIndex - 1 )*@pageSize + 1 set @endIndex = @pageIndex * @pageSize --执行sql语句 select * from (select *,ROW_NUMBER() over(order by Paid)as row from BlogPhotoAlblum where PaIsDel=0) as t where t.row>[email protected] and t.row<=@endIndex --给输出参数赋值 select @totalCount = COUNT(*)from BlogPhotoAlblum where PaIsDel=0 END
三、关于分页存储过程的一些扩展
首先是SQL语句:
select * from (select *,ROW_NUMBER() over(order by Paid)as row from BlogPhotoAlblum where PaIsDel=0) as t where t.row>[email protected] and t.row<[email protected]
这里采用了ROW_NUMBER()函数,
语法:ROW_NUMBER() OVER(PARTITION BY COLUMN ORDER BY COLUMN)
简单的说row_number()从1开始,为每一条分组记录返回一个数字,这里的ROW_NUMBER() OVER (ORDER BY xlh DESC) 是先把xlh列降序,再为降序以后的没条xlh记录返回一个序号。
示例:
xlh row_num
1700 1
1500 2
1085 3
710 4
row_number() OVER (PARTITION BY COL1 ORDER BY COL2) 表示根据COL1分组,在分组内部根据 COL2排序,而此函数计算的值就表示每组内部排序后的顺序编号(组内连续的唯一的)
实例:
初始化数据
create table employee (empid int ,deptid int ,salary decimal(10,2))
insert into employee values(1,10,5500.00)
insert into employee values(2,10,4500.00)
insert into employee values(3,20,1900.00)
insert into employee values(4,20,4800.00)
insert into employee values(5,40,6500.00)
insert into employee values(6,40,14500.00)
insert into employee values(7,40,44500.00)
insert into employee values(8,50,6500.00)
insert into employee values(9,50,7500.00)
数据显示为
empid deptid salary
----------- ----------- ---------------------------------------
1 10 5500.00
2 10 4500.00
3 20 1900.00
4 20 4800.00
5 40 6500.00
6 40 14500.00
7 40 44500.00
8 50 6500.00
9 50 7500.00
需求:根据部门分组,显示每个部门的工资等级
预期结果:
empid deptid salary rank
----------- ----------- --------------------------------------- --------------------
1 10 5500.00 1
2 10 4500.00 2
4 20 4800.00 1
3 20 1900.00 2
7 40 44500.00 1
6 40 14500.00 2
5 40 6500.00 3
9 50 7500.00 1
8 50 6500.00 2
SQL脚本:
SELECT *, Row_Number() OVER (partition by deptid ORDER BY salary desc) rank FROM employee