日期:2014-05-19  浏览次数:20354 次

求一通用分页SQL(不要存储过程)(C#实现)(已解决,公布结果)
基类
///   <summary>
///   执行SQL查询,返回分页记录集
///   </summary>
///   <param   name= "sql "> SQL语句 </param>
///   <param   name= "startRowIndex "> 开始行,1开始 </param>
///   <param   name= "maximumRows "> 最大返回行数 </param>
///   <param   name= "keyColumn "> 主键列。用于not   in分页 </param>
///   <returns> </returns>
public   virtual   DataSet   Query(String   sql,   Int32   startRowIndex,   Int32   maximumRows,   String   keyColumn)
{
//   从第一行开始,不需要分页
if   (startRowIndex   <=   1)
{
if   (maximumRows   <   1)
return   Query(sql);
else
return   Query(String.Format( "Select   Top   {0}   *   From   ({1})   a ",   maximumRows,   sql));
}
if   (maximumRows   <   1)
sql   =   String.Format( "Select   *   From   ({1})   b   Where   {2}   Not   In(Select   Top   {0}   {2}   From   ({1})   a) ",   startRowIndex   -   1,   sql,   keyColumn);
else
sql   =   String.Format( "Select   Top   {0}   *   From   ({1})   b   Where   {2}   Not   In(Select   Top   {3}   {2}   From   ({1})   a) ",   startRowIndex   +   maximumRows   -   1,   sql,   keyColumn,   startRowIndex   -   1);
return   Query(sql);
}

派生类
public   override   DataSet   Query(string   sql,   int   startRowIndex,   int   maximumRows,   string   keyColumn)
{
//   如果没有Order   By,直接调用基类方法
//   先用字符串判断,如果命中率高,这样可以提高处理效率
if   (!sql.Contains( "order "))   return   base.Query(sql,   startRowIndex,   maximumRows,   keyColumn);
if   (!sql.ToLower().Contains( "order "))   return   base.Query(sql,   startRowIndex,   maximumRows,   keyColumn);
//   使用正则进行严格判断。必须包含Order   By,并且它右边没有右括号),表明有order   by,且不是子查询的,才需要特殊处理
MatchCollection   ms   =   Regex.Matches(sql,   @ "\border\s*by\b[^)]+$ ",   RegexOptions.Compiled   |   RegexOptions.IgnoreCase);
if   (ms   ==   null   ||   ms.Count   <   1   ||   ms[0].Index   <   1)
{
return   base.Query(sql,   startRowIndex,   maximumRows,   keyColumn);
}
//   已确定该sql最外层含有order   by,再检查最外层是否有top。因为没有top的order   by是不允许作为子查询的
if   (!Regex.IsMatch(sql,   @ "^[^(]+\btop\b ",   RegexOptions.Compiled   |   RegexOptions.IgnoreCase))
{
return   base.Query(sql,   startRowIndex,   maximumRows,   keyColumn);
}
String   orderBy   =   sql.Substring(ms[0].Index);
sql   =   sql.Substring(0,   ms[0].Index);

//   从第一行开始,不需要分页
if   (startRowIndex   <=   1)
{
if   (maximumRows   <   1)
return   Query(sql);
else
return   Query(String.Format( "Select   Top   {0}   *   From   ({1})   a   {2} ",   maximumRows,   sql,   orderBy));