Access的快速分页法的bug修正

时间:2006/5/9 23:40:44      阅读:4193          

      在网上年到很多网站都写了不少关于DataGrid实现分页的方法,分页一直是很多初学ASP.NET的人感到棘手的问题,特别是自定义分页功能,实现方法多种多样,非常灵活。使用分页的缺点是DataGrid控件绑定到该DataSet之后,它的自动分页功能会帮你从该DataSet中筛选出当前分页的数据并显示出来,其他没有用的数据将被丢弃,对于小数量的记录,这种开销可能是比较小的,如果针对大量数据的分页,开销将会非常巨大,从而导致分页的速度非常的慢。换句话说,就算每个DataGrid分页面要显示的数据只是一个拥有几万条记录的数据库表的其中10条,每次DataGrid进行分页时还是要从该表中取出所有的记录。

      很多人已经意识到了这个问题,并提出了解决方法:用自定义分页,每次只从数据库中取出要显示的数据。这样,我们需要在SQL语句上下功夫了。由于Access不支持真正的存储过程,在编写分页算法上就没有SQL Server那么自由了。SQL Server可以在存储过程中利用临时表来实现高效率的分页算法,受到了广泛的采用。而对于Access,我们必须想办法在一条SQL语句内实现最高效的算法。用一条SQL语句取得某段数据的方法有好几种。算法不同,效率也就不同。我经过粗略的测试,发现效率最差的SQL语句执行时耗费的时间大概是效率最高的SQL语句的3倍!而且这个数值会随着记录总数的增加而增加。至于如何实现Access的快速分页的代码很多网站都有介绍,具体内容俺就不在此写这么多了。

      本文将针对各网站的Access数据库下的快速分页法的SQL句子修正了一些bug并转换成vb.net语法,以下是完整的函数:

 1    ''' <summary> 
 2    ''' 获取根据指定字段排序并分页查询的 SELECT 语句。 
 3    ''' </summary> 
 4    ''' <param name="pageSize">每页要显示的记录的数目。</param> 
 5    ''' <param name="pageIndex">要显示的页的索引。</param> 
 6    ''' <param name="recordCount">数据表中的记录总数。</param> 
 7    ''' <param name="tableName">要查询的数据表。</param> 
 8    ''' <param name="queryFields">要查询的字段。</param> 
 9    ''' <param name="primaryKey">主键字段。</param> 
10    ''' <param name="ascending">是否为升序排列。</param> 
11    ''' <param name="condition">查询的筛选条件。</param> 
12    ''' <returns>返回排序并分页查询的 SELECT 语句。</returns> 
13    ''' <remarks></remarks> 
14    Public Shared Function Paging(ByVal pageSize As Integer, ByVal pageIndex As Integer _
15, ByVal recordCount As Integer, ByVal tableName As String, ByVal queryFields As String _
16, ByVal primaryKey As String, ByVal ascending As Boolean, ByVal condition As String) As String 
17        Dim sb As New StringBuilder() 
18        Dim pageCount As Integer = GetPageCount(recordCount, pageSize)   ’分页的总数 
19        Dim middleIndex As Integer = GetMidPageIndex(pageCount)          ’中间页的索引 
20        Dim firstIndex As Integer = 0                                    ’第一页的索引 
21        Dim lastIndex As Integer = pageCount - 1                         ’最后一页的索引 
22 
23        If pageIndex <= firstIndex Then 
24            sb.Append("SELECT TOP ").Append(pageSize).Append(" ").Append(queryFields) _
25.Append(" FROM ").Append(tableName) 
26
27            If condition <> String.Empty Then 
28                sb.Append(" WHERE ").Append(condition) 
29            End If 
30            sb.Append(" ORDER BY ").Append(primaryKey).Append(" ").Append(GetSortType(ascending)) 
31        End If 
32
33        If pageIndex > firstIndex AndAlso pageIndex <= middleIndex Then 
34            sb.Append("SELECT TOP ").Append(pageSize).Append(" ").Append(queryFields).Append(" FROM ") _
35.Append(tableName).Append(" WHERE ").Append(primaryKey) 
36            If ascending Then 
37                sb.Append(" > (").Append(" SELECT MAX(") 
38            Else 
39                sb.Append(" < (").Append(" SELECT MIN(") 
40            End If 
41            sb.Append(primaryKey).Append(") FROM ( SELECT TOP ").Append((pageSize * pageIndex)) _
42.Append(" ").Append(primaryKey).Append(" FROM ").Append(tableName) 
43
44            If condition <> String.Empty Then 
45                sb.Append(" WHERE ").Append(condition) 
46            End If 
47            sb.Append(" ORDER BY ").Append(primaryKey).Append(" ").Append(GetSortType(ascending)) _
48.Append(" ) TableA )") 
49
50            If condition <> String.Empty Then 
51                sb.Append(" AND ").Append(condition) 
52            End If 
53            sb.Append(" ORDER BY ").Append(primaryKey).Append(" ").Append(GetSortType(ascending)) 
54        End If 
55        If pageIndex > middleIndex AndAlso pageIndex < lastIndex Then 
56            sb.Append("SELECT").Append(" ").Append(queryFields).Append(" FROM ( SELECT TOP ") _
57.Append(pageSize).Append(" ").Append(queryFields).Append(" FROM ") _
58.Append(tableName).Append(" WHERE ").Append(primaryKey) 
59            If ascending Then 
60                sb.Append(" < (").Append(" SELECT MIN(") 
61            Else 
62                sb.Append(" > (").Append(" SELECT MAX(") 
63            End If 
64            sb.Append(primaryKey).Append(") FROM ( SELECT TOP ") _
65.Append((recordCount - pageSize * (pageIndex + 1))) _
66.Append(" ").Append(primaryKey).Append(" FROM ").Append(tableName) 
67
68            If condition <> String.Empty Then 
69                sb.Append(" WHERE ").Append(condition) 
70            End If 
71            sb.Append(" ORDER BY ").Append(primaryKey).Append(" ").Append(GetSortType(Not ascending)) _
72.Append(" ) TableA )") 
73
74            If condition <> String.Empty Then 
75                sb.Append(" AND ").Append(condition) 
76            End If 
77            sb.Append(" ORDER BY ").Append(primaryKey).Append(" ").Append(GetSortType(Not ascending)) _
78.Append(" ) TableB ORDER BY ").Append(primaryKey).Append(" ").Append(GetSortType(ascending)) 
79        End If 
80        If pageIndex >= lastIndex Then 
81            sb.Append("SELECT").Append(" ").Append(queryFields).Append(" FROM ( SELECT TOP ") _
82.Append((recordCount - pageSize * lastIndex)).Append(" ").Append(queryFields).Append(" FROM ").Append(tableName) 
83            If condition <> String.Empty Then 
84                sb.Append(" WHERE ").Append(condition) 
85            End If 
86            sb.Append(" ORDER BY ").Append(primaryKey).Append(" ").Append(GetSortType(Not ascending)) _
87.Append(" ) TableA ORDER BY ").Append(primaryKey).Append(" ").Append(GetSortType(ascending)) 
88        End If 
89        Return sb.ToString() 
90    End Function

      修正bug后的sql语句支持多条件查询,具体详见http://www.web3.cn/vs2005/RepeaterPage_Access.aspx(本演示只做了一万多条记录的演示,使用快速分页的方法速度明显示比没有使用前要快得多)或本站的“技术交流“。本文就到这吧,还有很多地方需要大家在平时工作和学习中不断总结经验,在解决实际问题时尽可能找到最有效的方法。

评论
  • Re:Access的快速分页法的bug修正  (2006/8/16 14:24:57) by 飘萍 
        学习了,谢谢。。
标 题:
 
姓 名:
 
主 页:

验证码:

评论:
 

Because of the cache,you may see your comments several minutes later.