网上有很多分页存储过程,但是基本上都是提供一个单纯的存储过程,没有具体的怎样去实现。最近做一个项目用户的数数据相当大(一百万以上的数据),如果用.NET自带的分页基本上是跑不动了,不是提示超时就是死在那里。于是就想到用存储过程分页来实现,去网上逛了一大圈终于找了几个比较好的存储过程。接下去就开始做测试等等,最后就干脆把它做成用户控件算了,以后用直接拖到页面上,传几个属性进去就可以实现分页,免得每次都重复同样的code。
经本人测试,对于Sqlserver的效率相当快,而对于Oracle的效率(按某个字段倒序排)不是很理想,如果不排序效率很理想,这点没有深入研究(Oracle为什么按倒序排速度很慢,在PL/SQL里也一样)。
先发布SqlServer版的存储过程(网上下载):
CREATE PROCEDURE GetRecordFromPage
@tblName varchar(255), -- 表名
@RetColumns varchar(1000) = '*', -- 需要返回的列,默认为全部
@Orderfld varchar(255), -- 排序字段名
@PageSize int = 10, -- 页尺寸
@PageIndex int = 1, -- 页码
@IsCount bit = 0, -- 返回记录总数, 非 0 值则返回
@OrderType varchar(50) = 'asc', -- 设置排序类型, 非 asc 值则降序
@strWhere varchar(1000) = '' -- 查询条件 (注意: 不要加 where)
AS
declare @strSQL varchar(1000) -- 主语句
declare @strTmp varchar(300) -- 临时变量
declare @strOrder varchar(400) -- 排序类型
if @IsCount != 0 --执行总数统计
begin
if @strWhere != ''
set @strSQL = "select count(*) as Total from [" + @tblName + "] where " + @strWhere
else
set @strSQL = "select count(*) as Total from [" + @tblName + "]"
end
else --执行查询操作
begin
if @OrderType != 'asc'
begin
set @strTmp = "<(select min"
set @strOrder = " order by [" + @Orderfld +"] desc"
end
else
begin
set @strTmp = ">(select max"
set @strOrder = " order by [" + @Orderfld +"] asc"
end
set @strSQL = "select top " + str(@PageSize) + " " + @RetColumns + " from ["
+ @tblName + "] where [" + @Orderfld + "]" + @strTmp + "(["
+ @Orderfld + "]) from (select top " + str((@PageIndex-1)*@PageSize) + " ["
+ @Orderfld + "] from [" + @tblName + "]" + @strOrder + ") as tblTmp)"
+ @strOrder
if @strWhere != ''
set @strSQL = "select top " + str(@PageSize) + " " + @RetColumns + " from ["
+ @tblName + "] where [" + @Orderfld + "]" + @strTmp + "(["
+ @Orderfld + "]) from (select top " + str((@PageIndex-1)*@PageSize) + " ["
+ @Orderfld + "] from [" + @tblName + "] where (" + @strWhere + ") "
+ @strOrder + ") as tblTmp) and (" + @strWhere + ") " + @strOrder
if @PageIndex = 1
begin
set @strTmp = ""
if @strWhere != ''
set @strTmp = " where (" + @strWhere + ")"
set @strSQL = "select top " + str(@PageSize) + " " + @RetColumns + " from ["
+ @tblName + "]" + @strTmp + " " + @strOrder
end
end
exec (@strSQL)
@tblName varchar(255), -- 表名
@RetColumns varchar(1000) = '*', -- 需要返回的列,默认为全部
@Orderfld varchar(255), -- 排序字段名
@PageSize int = 10, -- 页尺寸
@PageIndex int = 1, -- 页码
@IsCount bit = 0, -- 返回记录总数, 非 0 值则返回
@OrderType varchar(50) = 'asc', -- 设置排序类型, 非 asc 值则降序
@strWhere varchar(1000) = '' -- 查询条件 (注意: 不要加 where)
AS
declare @strSQL varchar(1000) -- 主语句
declare @strTmp varchar(300) -- 临时变量
declare @strOrder varchar(400) -- 排序类型
if @IsCount != 0 --执行总数统计
begin
if @strWhere != ''
set @strSQL = "select count(*) as Total from [" + @tblName + "] where " + @strWhere
else
set @strSQL = "select count(*) as Total from [" + @tblName + "]"
end
else --执行查询操作
begin
if @OrderType != 'asc'
begin
set @strTmp = "<(select min"
set @strOrder = " order by [" + @Orderfld +"] desc"
end
else
begin
set @strTmp = ">(select max"
set @strOrder = " order by [" + @Orderfld +"] asc"
end
set @strSQL = "select top " + str(@PageSize) + " " + @RetColumns + " from ["
+ @tblName + "] where [" + @Orderfld + "]" + @strTmp + "(["
+ @Orderfld + "]) from (select top " + str((@PageIndex-1)*@PageSize) + " ["
+ @Orderfld + "] from [" + @tblName + "]" + @strOrder + ") as tblTmp)"
+ @strOrder
if @strWhere != ''
set @strSQL = "select top " + str(@PageSize) + " " + @RetColumns + " from ["
+ @tblName + "] where [" + @Orderfld + "]" + @strTmp + "(["
+ @Orderfld + "]) from (select top " + str((@PageIndex-1)*@PageSize) + " ["
+ @Orderfld + "] from [" + @tblName + "] where (" + @strWhere + ") "
+ @strOrder + ") as tblTmp) and (" + @strWhere + ") " + @strOrder
if @PageIndex = 1
begin
set @strTmp = ""
if @strWhere != ''
set @strTmp = " where (" + @strWhere + ")"
set @strSQL = "select top " + str(@PageSize) + " " + @RetColumns + " from ["
+ @tblName + "]" + @strTmp + " " + @strOrder
end
end
exec (@strSQL)
下面为用户控件前台html代码:
<%@ Control Language="c#" AutoEventWireup="false" Codebehind="GetPagerForSql.ascx.cs" Inherits="doHope.GetPagerForSql" TargetSchema="http://schemas.microsoft.com/intellisense/ie5"%>
<asp:label id="Label2" runat="server" Font-Size="9pt">共</asp:label><FONT face="宋体"> </FONT></FONT><asp:label id="lbl_RecordCnt" runat="server" Font-Size="9pt"></asp:label><FONT face="宋体"> </FONT><asp:label id="Label3" runat="server" Font-Size="9pt">项</asp:label><FONT face="宋体"> </FONT><asp:label id="Label4" runat="server" Font-Size="9pt" ForeColor="Black">|</asp:label><FONT face="宋体"> </FONT><asp:linkbutton id="lkbFirst" runat="server" Font-Size="9pt" Enabled="False" ForeColor="Black" CommandArgument="First">首页</asp:linkbutton><FONT face="宋体"> </FONT><asp:linkbutton id="lkbPre" runat="server" Font-Size="9pt" Enabled="False" ForeColor="Black" CommandArgument="Pre">上一页</asp:linkbutton><FONT face="宋体"> </FONT><asp:linkbutton id="lkbNext" runat="server" Font-Size="9pt" Enabled="False" ForeColor="Black" CommandArgument="Next">下一页</asp:linkbutton><FONT face="宋体"> </FONT><asp:linkbutton id="lkbLast" runat="server" Font-Size="9pt" Enabled="False" ForeColor="Black" CommandArgument="Last">末页</asp:linkbutton><FONT face="宋体"> </FONT><asp:label id="Label5" runat="server" Font-Size="9pt" ForeColor="Black">|</asp:label><FONT face="宋体"> </FONT><asp:label id="Label6" runat="server" Font-Size="9pt">转</asp:label><asp:textbox id="txt_CurrentPage" runat="server" Enabled="False" Width="35px" Height="18px" AutoPostBack="True"></asp:textbox><FONT face="宋体"></FONT>
<asp:label id="Label8" runat="server" Font-Size="9pt" ForeColor="Black">/</asp:label><FONT face="宋体"> </FONT><asp:label id="lbl_PageCnt" runat="server" Font-Size="9pt"></asp:label><FONT face="宋体"> </FONT><asp:label id="Label9" runat="server" Font-Size="9pt">页</asp:label>
<asp:label id="Label2" runat="server" Font-Size="9pt">共</asp:label><FONT face="宋体"> </FONT></FONT><asp:label id="lbl_RecordCnt" runat="server" Font-Size="9pt"></asp:label><FONT face="宋体"> </FONT><asp:label id="Label3" runat="server" Font-Size="9pt">项</asp:label><FONT face="宋体"> </FONT><asp:label id="Label4" runat="server" Font-Size="9pt" ForeColor="Black">|</asp:label><FONT face="宋体"> </FONT><asp:linkbutton id="lkbFirst" runat="server" Font-Size="9pt" Enabled="False" ForeColor="Black" CommandArgument="First">首页</asp:linkbutton><FONT face="宋体"> </FONT><asp:linkbutton id="lkbPre" runat="server" Font-Size="9pt" Enabled="False" ForeColor="Black" CommandArgument="Pre">上一页</asp:linkbutton><FONT face="宋体"> </FONT><asp:linkbutton id="lkbNext" runat="server" Font-Size="9pt" Enabled="False" ForeColor="Black" CommandArgument="Next">下一页</asp:linkbutton><FONT face="宋体"> </FONT><asp:linkbutton id="lkbLast" runat="server" Font-Size="9pt" Enabled="False" ForeColor="Black" CommandArgument="Last">末页</asp:linkbutton><FONT face="宋体"> </FONT><asp:label id="Label5" runat="server" Font-Size="9pt" ForeColor="Black">|</asp:label><FONT face="宋体"> </FONT><asp:label id="Label6" runat="server" Font-Size="9pt">转</asp:label><asp:textbox id="txt_CurrentPage" runat="server" Enabled="False" Width="35px" Height="18px" AutoPostBack="True"></asp:textbox><FONT face="宋体"></FONT>
<asp:label id="Label8" runat="server" Font-Size="9pt" ForeColor="Black">/</asp:label><FONT face="宋体"> </FONT><asp:label id="lbl_PageCnt" runat="server" Font-Size="9pt"></asp:label><FONT face="宋体"> </FONT><asp:label id="Label9" runat="server" Font-Size="9pt">页</asp:label>
下面为后台代码:
namespace doHope
{
using System;
using System.Data;
using System.Drawing;
using System.Web;
using System.Web.UI.WebControls;
using System.Web.UI.HtmlControls;
using System.Data.SqlClient;
/// <summary>
/// 配合存储过程分页自定义控件(Sql Server)
/// By Cherish58
/// </summary>
public class GetPagerForSql : System.Web.UI.UserControl
{
protected System.Web.UI.WebControls.Label Label1;
protected System.Web.UI.WebControls.Label Label9;
protected System.Web.UI.WebControls.Label lbl_PageCnt;
protected System.Web.UI.WebControls.Label Label6;
protected System.Web.UI.WebControls.LinkButton lkbLast;
protected System.Web.UI.WebControls.LinkButton lkbNext;
protected System.Web.UI.WebControls.LinkButton lkbPre;
protected System.Web.UI.WebControls.LinkButton lkbFirst;
protected System.Web.UI.WebControls.Label Label3;
protected System.Web.UI.WebControls.Label lbl_RecordCnt;
protected System.Web.UI.WebControls.Label Label2;
protected System.Web.UI.WebControls.Label Label4;
protected System.Web.UI.WebControls.Label Label5;
protected System.Web.UI.WebControls.Label Label7;
protected System.Web.UI.WebControls.Label Label8;
protected System.Web.UI.WebControls.TextBox txt_CurrentPage;
全局变量
属性
Page_Load
Web 窗体设计器生成的代码
分页 ChangePage
绑定数据
处理数据集
控制分页按扭状态
得到记录总数、总页数
跳转
传值后再绑定,用于有条件查询(前台调用)
}
}
{
using System;
using System.Data;
using System.Drawing;
using System.Web;
using System.Web.UI.WebControls;
using System.Web.UI.HtmlControls;
using System.Data.SqlClient;
/// <summary>
/// 配合存储过程分页自定义控件(Sql Server)
/// By Cherish58
/// </summary>
public class GetPagerForSql : System.Web.UI.UserControl
{
protected System.Web.UI.WebControls.Label Label1;
protected System.Web.UI.WebControls.Label Label9;
protected System.Web.UI.WebControls.Label lbl_PageCnt;
protected System.Web.UI.WebControls.Label Label6;
protected System.Web.UI.WebControls.LinkButton lkbLast;
protected System.Web.UI.WebControls.LinkButton lkbNext;
protected System.Web.UI.WebControls.LinkButton lkbPre;
protected System.Web.UI.WebControls.LinkButton lkbFirst;
protected System.Web.UI.WebControls.Label Label3;
protected System.Web.UI.WebControls.Label lbl_RecordCnt;
protected System.Web.UI.WebControls.Label Label2;
protected System.Web.UI.WebControls.Label Label4;
protected System.Web.UI.WebControls.Label Label5;
protected System.Web.UI.WebControls.Label Label7;
protected System.Web.UI.WebControls.Label Label8;
protected System.Web.UI.WebControls.TextBox txt_CurrentPage;
全局变量
属性
Page_Load
Web 窗体设计器生成的代码
分页 ChangePage
绑定数据
处理数据集
控制分页按扭状态
得到记录总数、总页数
跳转
传值后再绑定,用于有条件查询(前台调用)
}
}
使用时,只需传几个必须赋初值的属性即可:TableName为表或视图名,OrderField为排序字段,DataControlName为数据列表控件名称(这里默认是DataGrid控件,根据需要自己修改)。
里面有个InitBindData属性:初始登陆时是否绑定数据(是为true,否为false),默认为false。