生成多字段排序分页的SQL的通用类
程序员文章站
2023-03-13 19:37:09
如果的单一字段排序分页,现在有很多的存储过程和sql语句,分页的时候,只取pagesize的记录,可遇见的问题是: 这个单一字段必须是唯一的 这个字段必须是可以被排序的 不...
如果的单一字段排序分页,现在有很多的存储过程和sql语句,分页的时候,只取pagesize的记录,可遇见的问题是:
这个单一字段必须是唯一的
这个字段必须是可以被排序的
不支持多字段排序
针对这一问题,我用c#做了一个类,解决以上的对多字段排序分页和每次都取pagesize条记录的问题 先看看代码:
using system;
using system.collections.specialized;
namespace web
{
/// <summary>
/// multiorderpagersql 的摘要说明
/// </summary>
public class multiorderpagersql
{
private namevaluecollection orders = new namevaluecollection();
private string table_;
private string where_="";//1=1 and 2=2 的格式
private string outfields_;
private int nowpageindex_=0;
private int pagesize_=0;
private string sql_;//要返回的sql
public multiorderpagersql()
{
}
/****************方法*******************/
public void addorderfield(string field, string direction)
{
orders.add(field, direction);
}
public string getsql()
{
//排序字段
string orderlist="";//用户期望的排序
string orderlist2 = "";//对用户期望的排序的反排序
string orderlist3 = "";//用户期望的排序,去掉了前缀.复合查询里的外层的排序不能是类似这样的table1.id,要去掉table1.。
if (orders.count > 0)
{
string[] str = orders.allkeys;
foreach (string s in str)
{
string direction="asc";//默认一个方向
if (orders[s].tostring() == "asc")
direction = "desc";
//去掉前缀的字段名称
string s2 = "";
int index = s.indexof(".") + 1;
s2 = s.substring(index);
orderlist =orderlist + s +" "+ orders[s] +",";
orderlist2 = orderlist2 + s2 + " " + direction + ",";
orderlist3 = orderlist3 + s2 + " " + orders[s] + ",";
}
//去掉最后的,号
orderlist = orderlist.substring(0,orderlist.length-1);
orderlist2 = orderlist2.substring(0, orderlist2.length - 1);
orderlist3 = orderlist3.substring(0, orderlist3.length - 1);
}
//return orderlist2;
//形成sql
string strtemp;
strtemp = "select * from \n ( select top {7} * from ( select top {6} {0} from {1} \n";
if (where_ != "")
strtemp = strtemp + " where {2} \n";
if(orderlist!="")
strtemp = strtemp + " order by {3} ) as tmp order by {4} \n ) \n as tmp2 \n order by {5} \n";
strtemp = string.format(strtemp, outfields_, table_, where_, orderlist, orderlist2, orderlist3, nowpageindex_ * pagesize_, pagesize_);
return strtemp;
}
/****************属性*******************/
public string table
{
set { table_ = value; }
}
public string where
{
set { where_ = value; }
}
public string outfields
{
set { outfields_ = value; }
}
public int nowpageindex
{
set { nowpageindex_ = value; }
}
public int pagesize
{
set { pagesize_ = value; }
}
}
}
说一下原理先:其实很简单,由于ac和ms sql 2000 没有象ms sql 2005的row_number函数,我们就不能从这里下手了,比如你取第二页,那就是序号从10-20,我们先按照某一排序规则 把 前 20条的数据取出来,然后再按照先前的排序规则的反规则把这个数据反排序,再取前10条,那么这个时候就是要取的数据了,这个时候还没有结束,再把结果按照先前的排序规则排序即可。我觉得效率瓶颈会出现在排序上。看看是怎么来使用的:
using system;
using system.data;
using system.configuration;
using system.collections;
using system.web;
using system.web.security;
using system.web.ui;
using system.web.ui.webcontrols;
using system.web.ui.webcontrols.webparts;
using system.web.ui.htmlcontrols;
public partial class multiorderpagersqltest : system.web.ui.page
{
protected void page_load(object sender, eventargs e)
{
web.multiorderpagersql sql = new web.multiorderpagersql();
//sql.addorderfield("t1.id", "desc");//第一排序字段
sql.addorderfield("t1.hits", "desc");//第二排序字段
sql.table = "joke t1,type t2";
sql.outfields = "t1.*,t2.type";
sql.nowpageindex = 5;
sql.pagesize = 10;
sql.where = "t1.typeid=t2.typeid";
response.write(sql.getsql());
}
}
以上在ac和ms sql 2000(5)上测试通过。
暂时做出这样一个类,没有做成存储过程,要做的话,还有一点难度呢 ,呵呵。
这个单一字段必须是唯一的
这个字段必须是可以被排序的
不支持多字段排序
针对这一问题,我用c#做了一个类,解决以上的对多字段排序分页和每次都取pagesize条记录的问题 先看看代码:
复制代码 代码如下:
using system;
using system.collections.specialized;
namespace web
{
/// <summary>
/// multiorderpagersql 的摘要说明
/// </summary>
public class multiorderpagersql
{
private namevaluecollection orders = new namevaluecollection();
private string table_;
private string where_="";//1=1 and 2=2 的格式
private string outfields_;
private int nowpageindex_=0;
private int pagesize_=0;
private string sql_;//要返回的sql
public multiorderpagersql()
{
}
/****************方法*******************/
public void addorderfield(string field, string direction)
{
orders.add(field, direction);
}
public string getsql()
{
//排序字段
string orderlist="";//用户期望的排序
string orderlist2 = "";//对用户期望的排序的反排序
string orderlist3 = "";//用户期望的排序,去掉了前缀.复合查询里的外层的排序不能是类似这样的table1.id,要去掉table1.。
if (orders.count > 0)
{
string[] str = orders.allkeys;
foreach (string s in str)
{
string direction="asc";//默认一个方向
if (orders[s].tostring() == "asc")
direction = "desc";
//去掉前缀的字段名称
string s2 = "";
int index = s.indexof(".") + 1;
s2 = s.substring(index);
orderlist =orderlist + s +" "+ orders[s] +",";
orderlist2 = orderlist2 + s2 + " " + direction + ",";
orderlist3 = orderlist3 + s2 + " " + orders[s] + ",";
}
//去掉最后的,号
orderlist = orderlist.substring(0,orderlist.length-1);
orderlist2 = orderlist2.substring(0, orderlist2.length - 1);
orderlist3 = orderlist3.substring(0, orderlist3.length - 1);
}
//return orderlist2;
//形成sql
string strtemp;
strtemp = "select * from \n ( select top {7} * from ( select top {6} {0} from {1} \n";
if (where_ != "")
strtemp = strtemp + " where {2} \n";
if(orderlist!="")
strtemp = strtemp + " order by {3} ) as tmp order by {4} \n ) \n as tmp2 \n order by {5} \n";
strtemp = string.format(strtemp, outfields_, table_, where_, orderlist, orderlist2, orderlist3, nowpageindex_ * pagesize_, pagesize_);
return strtemp;
}
/****************属性*******************/
public string table
{
set { table_ = value; }
}
public string where
{
set { where_ = value; }
}
public string outfields
{
set { outfields_ = value; }
}
public int nowpageindex
{
set { nowpageindex_ = value; }
}
public int pagesize
{
set { pagesize_ = value; }
}
}
}
说一下原理先:其实很简单,由于ac和ms sql 2000 没有象ms sql 2005的row_number函数,我们就不能从这里下手了,比如你取第二页,那就是序号从10-20,我们先按照某一排序规则 把 前 20条的数据取出来,然后再按照先前的排序规则的反规则把这个数据反排序,再取前10条,那么这个时候就是要取的数据了,这个时候还没有结束,再把结果按照先前的排序规则排序即可。我觉得效率瓶颈会出现在排序上。看看是怎么来使用的:
复制代码 代码如下:
using system;
using system.data;
using system.configuration;
using system.collections;
using system.web;
using system.web.security;
using system.web.ui;
using system.web.ui.webcontrols;
using system.web.ui.webcontrols.webparts;
using system.web.ui.htmlcontrols;
public partial class multiorderpagersqltest : system.web.ui.page
{
protected void page_load(object sender, eventargs e)
{
web.multiorderpagersql sql = new web.multiorderpagersql();
//sql.addorderfield("t1.id", "desc");//第一排序字段
sql.addorderfield("t1.hits", "desc");//第二排序字段
sql.table = "joke t1,type t2";
sql.outfields = "t1.*,t2.type";
sql.nowpageindex = 5;
sql.pagesize = 10;
sql.where = "t1.typeid=t2.typeid";
response.write(sql.getsql());
}
}
以上在ac和ms sql 2000(5)上测试通过。
暂时做出这样一个类,没有做成存储过程,要做的话,还有一点难度呢 ,呵呵。