记得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的原意。

posted on 2007-06-26 15:04  使名扬  阅读(588)  评论(2编辑  收藏  举报