记得3,4年前我写oracle万能分页控件,那个时候还是有很多读者的。4年后再来谈分页控件。(实在太忙,也很久没有来博客园了),自己都觉得过时了。而且我要批判的还是MSDN上的经典文章(4年前我写oracle万能分页就是参考了这篇文章)
一直以来我都认为MSDN上的文章是经典的,微软出来的代demo码也是相当严谨的。
但是对于这个sqlserver万能分页控件4年来我一直很怀疑。(因为我都是用oracle的,所以很少用这个控件)
最近在埃塞实在是没事可做了。又翻出这个文章来看。
关于以sql语句作为参数的万能分页方法有不少。
有的是
select Top(@PageSize) from TableName where ID Not IN
(Select Top ((@PageIndex-1)*@PageSize) ID from Table Name where .... order by ... )
where .... order by ...
但是Not in一用,性能极差。
在Dino Esposito 《Creating a Pager Control for ASP.NET》一文中所用的sql组合我现在还是比较认可。
SELECT * FROM
(SELECT TOP ItemsPerPage * FROM
(SELECT TOP ItemsPerPage*CurrentPageIndex * FROM
(SelectCommand) AS t0
ORDER BY SortField ASC) AS t1
ORDER BY SortField DESC) AS t2
ORDER BY SortField
但是他最大的错误在于它居然是用下面这段代码来实现的。
private string QueryPageCommandText = "SELECT * FROM " +
"(SELECT TOP {0} * FROM " +
"(SELECT TOP {1} * FROM ({2}) AS t0 ORDER BY {3} {4}) AS t1 " +
"ORDER BY {3} {5}) AS t2 " +
"ORDER BY {3}";
string cmdText = String.Format(QueryPageCommandText,
recsToRetrieve, // {0} --> page size
ItemsPerPage * (CurrentPageIndex + 1), // {1} --> size * index
SelectCommand, // {2} --> base query
SortField, // {3} --> key field in the query
"ASC", // Default to ascending order
"DESC");
对于只一个sort field的简单sql没有错。但对于复杂的就有问题
比如以Northwind的一个sql为例
SELECT Employees.LastName, Employees.FirstName,
Orders.OrderID
FROM Employees INNER JOIN
Orders ON
Employees.EmployeeID = Orders.EmployeeID
ORDER BY Orders.OrderID,Employees.FirstName
依据原理的本意 ORDER BY SortField DESC) AS t2
实现后应该是
ORDER BY OrderID desc, FirstName desc)AS t2
然按照demo控件,只是简单替换的话,实现后是
ORDER BY OrderID ,FirstName desc)AS t2
最后的结果并不符合SQL的原意。