Oracle分页之一:最普通的分页方式

今天我要说的就是基于Oracle存储过程的一种简单的分页方式,首先就是页面前端发起对分页的请求,然后向Oracle存储过程中传入页面当前数,页面大小,查询的SQL语句,而存储过程返回来的则是数据总条数和当前页面要显示的数据集合。形式如下所示:

procedure P_GetPageSize(p_pagesize int,

                        p_startsize int,

                        p_sqlQuery varchar2,

                        out_pagecount out int,

                        out_datacollection out outData);

其中p_pagesize则是传入的每页显示的条数,p_startsize则是传入的页面索引,p_sqlQuery则是传入的SQL语句,out_pagecount则是返回的总记录条数,out_datacollection则是返回的数据集合。

上面就是分页存储过程的定义,在Oracle中,我写成了包,具体代码如下:

 

create   or   replace  package scott.P_GetPageSize_pak
is
type outData 
is  ref  cursor ;
procedure  P_GetPageSize(p_pagesize  int ,
                        p_startsize 
int ,
                        p_sqlQuery 
varchar2 ,
                        out_pagecount out 
int ,
                        out_datacollection out outData);
end  P_GetPageSize_pak;
create   or   replace  package body scott.P_GetPageSize_pak
is
procedure  P_GetPageSize(p_pagesize  int ,
                          p_startsize 
int ,
                          p_sqlQuery 
varchar2 ,
                          out_pagecount out 
int ,
                          out_datacollection out outData) 
as
v_sql 
varchar2 ( 3000 );
v_count 
int ;
v_upCount 
int ;
v_lowCount 
int ;
begin
     
-- 获取页面总的记录数
    
execute  immediate  ' select count(*) from ( ' || p_sqlQuery || ' ) '   into  v_count;
    out_pagecount:
= v_count;
    
-- 获取数据的上下限
    v_upCount:
= p_startsize * p_pagesize;    -- 上限
    v_lowCount:
= v_upCount - p_pagesize + 1 -- 下限
   
    v_sql:
= ' select * from (select a.*,rownum r from ( ' || p_sqlQuery || ' ) a where rownum <= ' || to_char(v_upCount) || ' ) B
               where r>=
' || to_char(v_lowCount);
    
open  out_datacollection  for  v_sql;
end  P_GetPageSize;
end  P_GetPageSize_pak;

 

上面的流程就是先获取页面的记录总数,然后利用select into 将其写入到out_pagecount变量中。然后再根据当前页面索引和每页显示的记录条数来得到需要返回的开始和截止记录条数。

最后返回数据集即可。

存储过程暂时在此打住,现在主要就是页面的处理了。

asp.net页面中,处理Oracle中的包,就是利用形如“包头.存储过程名称(参数)“的方式引用即可。

具体代码示例如下(类Pagination.cs):

using  System;
using  System.Collections.Generic;
using  System.Web;
using  System.Data;
using  System.Data.OracleClient;
using  System.Configuration;
///   <summary>
/// Pagination 的摘要说明
///   </summary>
public   class  Pagination
{
    
public  Pagination() { }
    
public   static   string  connStr  =  ConfigurationManager.ConnectionStrings[ " Oracle-MS " ].ToString();
    
public   static  OracleConnection CreateConn()
    {
        OracleConnection conn 
=   new  OracleConnection(connStr);
        conn.Open();
        
return  conn;
    }
    
public   static  DataSet PaginationPager( string  sqlQuery,  int  _pageSize,  int  _startsize,  out   int  _sqlCount)
    {
        DataSet ds 
=   new  DataSet();
        
using  (OracleConnection conn  =  CreateConn())
        {            
            OracleCommand cmd 
=   new  OracleCommand();
            cmd.Connection 
=  conn;
            cmd.CommandText 
=   " P_GetPageSize_pak.P_GetPageSize " ;
            cmd.CommandType 
=  CommandType.StoredProcedure;

            cmd.Parameters.Add(
" p_pagesize " , OracleType.Int32);
            cmd.Parameters[
" p_pagesize " ].Direction  =  ParameterDirection.Input;
            cmd.Parameters[
" p_pagesize " ].Value  =  _pageSize;
 
            cmd.Parameters.Add(
" p_startsize " , OracleType.Int32);
            cmd.Parameters[
" p_startsize " ].Direction  =  ParameterDirection.Input;
            cmd.Parameters[
" p_startsize " ].Value  =  _startsize;
 
            cmd.Parameters.Add(
" p_sqlQuery " , OracleType.VarChar);
            cmd.Parameters[
" p_sqlQuery " ].Direction  =  ParameterDirection.Input;
            cmd.Parameters[
" p_sqlQuery " ].Value  =  sqlQuery;

            cmd.Parameters.Add(
" out_pagecount " , OracleType.Int32);
            cmd.Parameters[
" out_pagecount " ].Direction  =  ParameterDirection.Output;
          
            cmd.Parameters.Add(
" out_datacollection " , OracleType.Cursor);
            cmd.Parameters[
" out_datacollection " ].Direction  =  ParameterDirection.Output;
            OracleDataAdapter oda 
=   new  OracleDataAdapter(cmd);         
            oda.Fill(ds);
            _sqlCount 
=  Int32.Parse(cmd.Parameters[ " out_pagecount " ].Value.ToString());  // 这句一定要放到fill方法后
        }
        
return  ds;
    }
}

上面的流程主要就是先打开Oracle数据库,然后将参数传入,最后将查询得到的数据总条数通过out参数进行值的保留,在被引用的时候,给引用传递过去;将数据集合填充到DataSet中给返回回去。

那么在页面中,如何使用分页类呢?

要实现分页,首先得拖入四个按钮,分别为“首页“、”上一页“、”下一页“、”尾页“,然后写入响应的响应事件函数即可。

需要注意的是,这里一定要正确的判断页尾和页首,然后只要数据到达页首,“首页“按钮和”上一页“按钮使能失效,而数据叨叨页尾,”下一页“、”尾页“使能失效。

具体请看页面代码:

using  System;
using  System.Collections.Generic;
using  System.Linq;
using  System.Web;
using  System.Web.UI;
using  System.Web.UI.WebControls;
using  System.Data;
public   partial   class  _Default : System.Web.UI.Page 
{
    
public   static   int  _pageSize  =   10 ;
    
public   static   int  _startSize  =   1 ;
    
public   static   int  totalCount;
    
protected   void  Page_Load( object  sender, EventArgs e)
    {
        
if  ( ! IsPostBack)
        {
            Bind();
        }
    }
    
private   void  Bind()
    {
        
string  sqlQuery  =   " select nsrsbm,nsr_mc,djlx_mc,dj_ztmc,zclx_mc,gljg_mc,zgy_mc,ssx_mc from scott.t_yhs_djxxtz " ;
        DataSet ds 
=  Pagination.PaginationPager(sqlQuery, _pageSize, _startSize,  out    totalCount);
        GridView1.DataSource 
= ds.Tables[ " Table " ] ;
        GridView1.DataBind();
         if  (_startSize  <=   1 // 如果当前为第一页
        {
            
if  (_startSize  *  _pageSize  >=  totalCount)  // 如果当前总条数小于一页的条数 那么按钮全部为不可用状态
            {
                lbtnFirst.Enabled 
=   false ;
                lbtnPrev.Enabled 
=   false ;
                lbtnNext.Enabled 
=   false ;
                lbtnEnd.Enabled 
=   false ;
            }
            
else   // 如果当前总条数大于一页的条数,那么首页 上一页 不可用,下一页 末页 可用
            {
                lbtnFirst.Enabled 
=   false ;
                lbtnPrev.Enabled 
=   false ;
                lbtnNext.Enabled 
=   true ;
                lbtnEnd.Enabled 
=   true ;
            }
        }
        
else   // 如果当前页数不是第一页
        {
            
if  ((totalCount  -  _startSize  *  _pageSize)  /  _pageSize  ==   0 // 表明到达了最后一页
            {
                lbtnFirst.Enabled 
=   true ;
                lbtnPrev.Enabled 
=   true ;
                lbtnNext.Enabled 
=   false ;
                lbtnEnd.Enabled 
=   false ;
            }
            
else
            {
                lbtnFirst.Enabled 
=   true ;
                lbtnPrev.Enabled 
=   true ;
                lbtnNext.Enabled 
=   true ;
                lbtnEnd.Enabled 
=   true ;
            }
        }
        
int  pageCount  =  ((totalCount  %  _pageSize)  ==   0 ?  (totalCount  /  _pageSize) : ((totalCount  /  _pageSize)  +   1 );
        lblInfo.Text 
=   " 当前第 "   +  _startSize  +   " 页,总共 "   +  pageCount  +   " " ;
    }
    
protected   void  lbtnFirst_Click( object  sender, EventArgs e)
    {
        
int  pageCount  =  ((totalCount  %  _pageSize)  ==   0 ?  (totalCount  /  _pageSize) : ((totalCount  /  _pageSize)  +   1 );
        _startSize 
=   1 ;
        Bind();
        lblInfo.Text 
=   " 当前第 " + _startSize + " 页,总共 " + pageCount + " " ;
    }
    
protected   void  lbtnPrev_Click( object  sender, EventArgs e)
    {
        
int  pageCount  =  ((totalCount  %  _pageSize)  ==   0 ?  (totalCount  /  _pageSize) : ((totalCount  /  _pageSize)  +   1 );
        
if  (_startSize  >   1 )
        {
            _startSize 
=  _startSize  -   1 ;
            Bind();
        }
        lblInfo.Text 
=   " 当前第 "   +  _startSize  +   " 页,总共 "   +  pageCount  +   " " ;
    }
    
protected   void  lbtnNext_Click( object  sender, EventArgs e)
    {
        
int  pageCount = ((totalCount % _pageSize) == 0 ) ? (totalCount / _pageSize):((totalCount / _pageSize) + 1 );
        
if  (_startSize  <  pageCount)
        {
            _startSize 
=  _startSize  +   1 ;
            Bind();
        }
        lblInfo.Text 
=   " 当前第 "   +  _startSize  +   " 页,总共 "   +  pageCount  +   " " ;
    }

    
protected   void  lbtnEnd_Click( object  sender, EventArgs e)
    {

        
int  pageCount = ((totalCount % _pageSize) == 0 ) ? (totalCount / _pageSize):((totalCount / _pageSize) + 1 );
        _startSize 
=  pageCount;
        Bind();
        lblInfo.Text 
=   " 当前第 "   +  _startSize  +   " 页,总共 "   +  pageCount  +   " " ;
    }
}

在asp.net前端的代码如下:

 

<% @ Page Language = " C# "  AutoEventWireup = " true "  CodeFile = " PagerWithCommonMethods.aspx.cs "  Inherits = " _Default "   %>
< html  xmlns ="http://www.w3.org/1999/xhtml" >
< head  runat ="server" >
    
< title > 测试Oracle的分页存储过程 </ title >
    
< link  href ="css/TableZB.css"  rel ="stylesheet"  type ="text/css"   />
    
< link  href ="css/swcss.css"  rel ="stylesheet"  type ="text/css"   />
    
< link  href ="css/GridViewCSS_O.css"  rel ="stylesheet"  type ="text/css"   />
    
< style  type ="text/css" >
    .Pager
    
{
        margin
: 5px ;
        text-align
: right ;
    
}
    .Pager a
    
{
        color
: Red ;
    
}
    .Pager a:hover
    
{
        color
: Blue ;
    
}
    .Pager a:visited
    
{
        text-decoration
: none ;
        font-size
: 12px ;
        color
: Red ;
    
}
    
</ style >
</ head >
< body >
    
< form  id ="form1"  runat ="server"  style ="width: 100%" >
    
< asp:GridView  CssClass ="GVtable"  ID ="GridView1"  runat ="server"  Width ="100%"    AutoGenerateColumns ="False" >
        
< Columns >
        
< asp:TemplateField  HeaderText ="纳税人识别码" >
        
< ItemTemplate > <% # Eval ( " nsrsbm " ).ToString()  %> </ ItemTemplate >
        
</ asp:TemplateField >
         
< asp:TemplateField  HeaderText ="纳税人名称" >
        
< ItemTemplate >   <% # Eval ( " nsr_mc " %> </ ItemTemplate >
        
</ asp:TemplateField >
         
< asp:TemplateField  HeaderText ="登记类型" >
        
< ItemTemplate > <% # Eval ( " djlx_mc " ) %> </ ItemTemplate >
        
</ asp:TemplateField >
         
< asp:TemplateField  HeaderText ="登记状态" >
        
< ItemTemplate > <% # Eval ( " dj_ztmc " ) %> </ ItemTemplate >
        
</ asp:TemplateField >
         
< asp:TemplateField  HeaderText ="注册类型" >
        
< ItemTemplate > <% # Eval ( " zclx_mc " ) %> </ ItemTemplate >
        
</ asp:TemplateField >
         
< asp:TemplateField  HeaderText ="所别" >
        
< ItemTemplate > <% # Eval ( " gljg_mc " ) %> </ ItemTemplate >
        
</ asp:TemplateField >
         
< asp:TemplateField  HeaderText ="专管员" >
        
< ItemTemplate > <% # Eval ( " zgy_mc " ) %> </ ItemTemplate >
        
</ asp:TemplateField >
         
< asp:TemplateField  HeaderText ="所属性"
        
< ItemTemplate > <% # Eval ( " ssx_mc " ) %> </ ItemTemplate >
        
</ asp:TemplateField >
        
</ Columns >
    
</ asp:GridView >
    
< div  class ="Pager" >
    
< asp:LinkButton  ID ="lbtnFirst"  runat ="server"  onclick ="lbtnFirst_Click" > 首页 </ asp:LinkButton >
    
< asp:LinkButton  ID ="lbtnPrev"  runat ="server"  onclick ="lbtnPrev_Click" > 上一页 </ asp:LinkButton >
    
< asp:LinkButton  ID ="lbtnNext"  runat ="server"  onclick ="lbtnNext_Click" > 下一页 </ asp:LinkButton >
    
< asp:LinkButton  ID ="lbtnEnd"  runat ="server"  onclick ="lbtnEnd_Click" > 末页 </ asp:LinkButton >
        
< asp:Label  ID ="lblInfo"  runat ="server"  Text ="" ></ asp:Label >
    
</ div >
    
</ form >
</ body >
</ html >

好了 具体的页面效果请看下图:

 

 

到这里就完成了,不过,很不完美,如果项目中好多地方要引用这个存储过程分页的话, 那不是每次都要拖入控件,然后写一大堆代码吗?这样不累死人吗?

呵呵 ,当然不是的,下节就讲如何将分页函数封装到web用户控件上,然后用户直接调用即可。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值