博客园  :: 首页  :: 新随笔  :: 联系 :: 管理

store 的数据库端分页

Posted on 2010-03-19 23:15  codingsilence  阅读(188)  评论(0编辑  收藏  举报
 

if ( 鄙视用sql语句 and 不屑oracle )
                              {  
                                 break;
                               }

经常有人问起关于数据库端分页的问题,包括利用存储过程之类的方法有很多,今天我尝试着利用一个更简单的方法来处理一下,就是抽出按某种方式排序的记录集中的第M条记录开始的X条记录,也就是在SqlServer里面的select top的方法。首先说明一下的是我用的数据库是oracle,但是原理差不多。

由于ORACLE不支持SELECT  TOP语句,所以在ORACLE中经常是用ORDER BY跟ROWNUM RECNO的组合来实现SELECT TOP N的查询。
我们知道,ROWNUM RECNO是记录表中数据编号的一个隐藏子段,(根据用户查询的结果,自动由1到N编号)所以可以在得到TOP N条记录的时候同时抽出记录的ROWNUM,然后再从这N条记录中抽取记录编号为M的记录,即使我们希望得到的结果。

在得到了TOP N的数据之后,为了抽出这N条记录中的第M条记录,我们可以考虑从ROWNUM着手。我们知道,ROWNUM是记录表中数据编号的一个隐藏子段,所以可以在得到TOP N条记录的时候同时抽出记录的ROWNUM,然后再从这N条记录中抽取记录编号为M的记录,即使我们希望得到的结果。

那么其语法就很简单了:
SELECT 列名1...列名n FROM
     (
      SELECT ROWNUM RECNO, 列名1...列名nFROM
       (
       SELECT 列名1...列名n FROM 表名 ORDER BY 列名1...列名n)
       WHERE ROWNUM <= N (N >= (M + X - 1))
     ORDER BY ROWNUM ASC
       )
      WHERE RECNO BETWEEN M AND (M + X - 1)
从以上语法可以知道,这个时候只需要得到M和X就可以完成使用sql语句来进行分页。

/////////////////////////////////////////分割线,对于只需要知道怎么做,不需要知道原理的同学,上面的就是废话了//////////////////////////////

下面具体实现:

为了得到M和X,我们必须要在store里面定义,让store来触发分页
  1. <ext:Store ID="Store2" runat="server"
  2.   OnRefreshData="Store2_Refresh">
  3.         <AutoLoadParams>
  4.             <ext:Parameter Name="start" Value="0" Mode="Raw" />            //定义从数据库中第几行开始查询
  5.             <ext:Parameter Name="limit" Value="10" Mode="Raw" />           //定义每次查询几行数据
  6.         </AutoLoadParams>
  7.         <Proxy>
  8.             <ext:DataSourceProxy />                                                              //这个应该是store的datasource的一个啥代理,原理不清楚,但必须的
  9.         </Proxy>
  10.         <Reader>
  11.         </Reader>   
  12.     </ext:Store>
复制代码
store的定义完成,然后是写刷新事件。
由于开头我说过,是用sql语句来做的,所以要想办法得到一条sql语句:
  1.     private string getPageStr(string tbName, int start, int limit)  //语句好长啊  -_-!
  2.   {
  3.         string s;
  4.         s = "SELECT * from(SELECT  ROWNUM RECNO, BILL_OUT_DT_ID,BILL_OUT_NO"+
  5.             " FROM    (SELECT * FROM VW_BILL_OUT_DT ORDER BY BILL_OUT_DT_ID)" +
  6.             " WHERE ROWNUM <= " + (start+1+ limit) + "          ORDER BY ROWNUM ASC )" +
  7.             "WHERE RECNO BETWEEN " + (start+1) + " AND " + (start+ limit) +" ";
  8.         return s;
  9.     }
复制代码
接下来就好办多了:
  1.     public void Store2_Refresh(object sender, StoreRefreshDataEventArgs e)
  2.     {
  3.        //
  4.         string sql = getPageStr("VW_BILL_OUT_DT", e.Start, e.Limit);
  5.         string sql1 = "select * from VW_BILL_OUT_DT";        
  6.         System.Data.DataSet ds1 = new System.Data.DataSet();
  7.          System.Data.DataSet ds2 = new System.Data.DataSet();
  8.         ds1 = Common.OraDbHelper.DbHelper.GetDataSet(sql1, "VW_BILL_OUT_DT");//为store准备datasource
  9.         ds1 = Common.OraDbHelper.DbHelper.GetDataSet(sql2, "VW_BILL_OUT_DT");//主要是取得数据库全部数据总数,为分页做准备
  10.      e.TotalCount = ds.Tables[0].Rows.Count;//告诉store有多少数据
  11.         Store2.DataSource = SqlDataSource1;
  12.         Store2.DataBind();        
  13.     }
复制代码
运行,完成!