发一段非万能的sql分页代码

百度一下,发现N多万能的sql分页办法, 不过大都有一个共性,就是把一段sql的各个部分折成几个参数,然后拼接sql

而且很多都只支持单表.

我发的代码就是为了解决上面这两个问题的.

使用注意事项:

1.传入的sql必须是可以正常执行的sql

2.传入的sql必须有排序(order by )

3.如果使用的是SqlServerDialect,最好传入正确totalCount,否则最后一页的数据可能跟你想像中的不太一样,

如果是SqlServer2005Dialect的话,不存在此问题

4.基本上可以满足绝大部分的sql语句,大家可以试试复杂的sql,有兴趣的话,可以跟我联系,大家一起完善

下面这段是针对sql server 2000的,不过2005与2008一样可以用

publicclass SqlServerDialect:ISqlDialect
{
#region ISqlDialect 成员

publicstring GetPageSqlText(string sql, int pageSize, int pageNum, int totalCount)
{
if (string.IsNullOrEmpty(sql))
return sql;


string orderByText = GetOrderByText(sql);
if (string.IsNullOrEmpty(orderByText))
thrownew ArgumentException("缺少order by ");

if (pageNum ==1)
return GetFirstPageSqlText(sql, pageSize);

int rowCount = pageSize;
if (totalCount >0)
{
if (totalCount < pageNum * pageSize)
{
rowCount
= totalCount - (pageNum -1) * pageSize;
}
if (rowCount <0)
rowCount
=0;
}

int pos = sql.IndexOf("select", StringComparison.OrdinalIgnoreCase);
if (pos <0)
thrownew ArgumentException("缺少select关键字", sql);

//string orderByText = GetOrderByText(sql);
string reverseOrderByText = GetReverseOrderByText(orderByText);
StringBuilder sb
=new StringBuilder();
sb.AppendFormat(
"select * from ( select top {0} * from ( select top {1}", rowCount, pageSize * pageNum);
sb.Append(sql.Substring(pos
+"select".Length));

sb.Append(
") as temptable1 order by ");
sb.Append(reverseOrderByText);
sb.Append(
") as temptable2 order by ");
sb.Append(orderByText);
return sb.ToString();

}

#endregion

privatestaticstring GetFirstPageSqlText(string sql, int pageSize)
{
int pos = sql.IndexOf("select", StringComparison.OrdinalIgnoreCase);
if (pos <0)
thrownew ArgumentException("缺少select关键字", sql);

StringBuilder sb
=new StringBuilder(sql.Length +20);
sb.Append(sql);
sb.Insert(pos
+"select".Length +1, String.Format("top {0} ", pageSize));
return sb.ToString();
}

privatestaticstring GetOrderByText(string sql)
{
int len ="order by".Length;
int pos = sql.LastIndexOf("order by", StringComparison.OrdinalIgnoreCase);
if (pos <0)
{
returnstring.Empty; ;
}
return RemoveAlias(sql.Substring(pos + len));
}

privatestaticstring GetReverseOrderByText(string orderByText)
{
StringBuilder sb
=new StringBuilder();
string[] cols = orderByText.Split(',');

for (int i =0; i < cols.Length; i++)
{
if (i >0)
sb.Append(
",");
int pos = cols[i].LastIndexOf(" desc", StringComparison.OrdinalIgnoreCase);
if (pos >-1)
{
sb.Append(cols[i].Substring(
0, pos)).Append(" asc");
}
else
{
pos
= cols[i].LastIndexOf(" asc", StringComparison.OrdinalIgnoreCase);
if (pos >-1)
{
sb.Append(cols[i].Substring(
0, pos)).Append(" desc");
}
else
{
sb.Append(cols[i]).Append(
" desc");
}
}
}
return sb.ToString();

}

privatestaticstring RemoveAlias(string orderByText)
{
StringBuilder sb
=new StringBuilder();

string[] cols = orderByText.Split(',');

for (int i =0; i < cols.Length; i++)
{
if (i >0)
sb.Append(
",");

int pos = cols[i].IndexOf(".");

if (pos >-1)
{
sb.Append(cols[i].Substring(pos
+1));
}
else
{
sb.Append(cols[i]);
}
}
return sb.ToString();

}

}

接着来个sqlserver2005的

publicclass SqlServer2005Dialect : ISqlDialect
{
#region ISqlDialect 成员

publicstring GetPageSqlText(string sql, int pageSize, int pageNum, int totalCount)
{
if (string.IsNullOrEmpty(sql))
return sql;

string orderByText = GetOrderByText(sql);
if (string.IsNullOrEmpty(orderByText))
thrownew SqlNullValueException("缺少order by ");


if (pageNum ==1)
return GetFirstPageSqlText(sql, orderByText, pageSize);

int startIndex = (pageNum -1) * pageSize;
int endIndex = startIndex + pageSize;

int pos = sql.IndexOf("select", StringComparison.OrdinalIgnoreCase);
if (pos <0)
thrownew ArgumentException("缺少select关键字", sql);

StringBuilder sb
=new StringBuilder();
sb.Append(sql);
sb.Insert(pos
+"select".Length +1, String.Format(" top 100 percent row_number() OVER(order by {0}) AS _rowNum, ", orderByText));
sb.AppendFormat(
" ) select * from _pageSql where _rowNum between {0} and {1} ", startIndex +1, endIndex);
sb.Insert(
0, "with _pageSql as ( ");

return sb.ToString();
}

#endregion

privatestaticstring GetFirstPageSqlText(string sql, string orderBySql, int pageSize)
{
int pos = sql.IndexOf("select", StringComparison.OrdinalIgnoreCase);
if (pos <0)
thrownew ArgumentException("缺少select关键字", sql);

StringBuilder sb
=new StringBuilder(sql.Length +20);
sb.Append(sql);
sb.Insert(pos
+"select".Length +1, String.Format("top {0} ", pageSize));
//sb.Append(" " + orderBySql);
return sb.ToString();
}

privatestaticstring GetOrderByText(string sql)
{
int len ="order by".Length;
int pos = sql.LastIndexOf("order by", StringComparison.OrdinalIgnoreCase);
if (pos <0)
{
returnstring.Empty; ;
}
return sql.Substring(pos + len);
}

}

像oracle/sqlite/mysql的,就很简单,不发了.

顺便把接口也发一下

publicinterface ISqlDialect
{
string GetPageSqlText(string sql, int pageSize, int pageNum, int totalCount);

}
posted @ 2011-07-19 00:17  builderman  阅读(2206)  评论(4编辑  收藏  举报