踢西工作室

踢西工作室:代码实例,网站重构,XHTML+CSS

  博客园 :: 首页 :: 博问 :: 闪存 :: 新随笔 :: 联系 :: 订阅 订阅 :: 管理 ::

      在网上年到很多网站都写了不少关于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(本演示只做了一万多条记录的演示,使用快速分页的方法速度明显示比没有使用前要快得多)或本站的“技术交流“。本文就到这吧,还有很多地方需要大家在平时工作和学习中不断总结经验,在解决实际问题时尽可能找到最有效的方法。

posted on 2006-05-28 00:18  踢西  阅读(402)  评论(0编辑  收藏  举报