要实现这么一个功能的函数:
输入参数:一个取得记录集的Select SQL,开始行行号,最大返回行数,唯一键列名
返回:返回一个基于给出的SQL的分页SQL
我实现的一个函数如下:
/// <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);
}
在实际应用中发现,对于Access,该方法可行,对于MSSQL,就不一定了。
如果参数中的sql带有order by,而又没有top,那么,这个SQL是不能作为子查询的,上面的方法就行不通了。
后来我又加了下面一个函数:
/// <summary>
/// 为子查询准备。
/// 如果一个SQL用了order by,而没有top时,在SqlServer中是不能作为子查询的。
/// </summary>
/// <param name= "sql "> </param>
/// <returns> </returns>
private String PrepairSqlForSubSelect(String sql)
{
String str = sql.Trim().ToLower();
// Select开头,不是存储过程
if (str.StartsWith( "select ") && str.Contains( "order by "))
{
str = str.Substring(0, 30);
if (!Regex.IsMatch(str, @ "^ *select( +(all|distinct))? +top ", RegexOptions.IgnoreCase))
{
sql = Regex.Replace(sql, @ "^ *select +all ", "Select All Top 100000000 ", RegexOptions.IgnoreCase);
sql = Regex.Replace(sql, @ "^ *select +distinct ", "Select Top 100000000 ", RegexOptions.IgnoreCase);
sql = Regex.Replace(sql, @ "^ *select + ", "Select Top 100000000 ", RegexOptions.IgnoreCase);
}
}
return sql;
}
用来检查参数sql是否是这种情况,如果是的话,用正则修改这个sql,在select后面加上Top 100000000。可以解决一部分问题。
后来又发现,如果参数sql中,select后面的选择列中带有ntext类型字段的话,是不能用top。
我现在没办法了,请各位帮帮忙。
存储过程的方法就不用啦,谢谢^_^
------解决方案--------------------------------------------------------