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