优化后的通用分页存储过程

 

前段时间由于项目需求想上网搜个通用分页存储过程先用着
本以为非常简单的事竟然让我大失所望
竟然没有一个能够满足我的需求,不是效率太低就是限制太多不符合实际需要
bug也是一顿狂冒,更有甚者执行都执行不了
我想应该很多朋友都有这样的遭遇吧
于是一气之下决定自己研究

在众多分析性能的文章中,很庆幸翻到了这一篇http://www.codeproject.com/aspnet/PagingLarge.asp(感谢园子里一位朋友的提示,具体名字已经不记得了),对分页存储过程有兴趣的朋友可以去看,写的很详尽,随便PF一下国外同行的认真和专业.

在上面提到的那篇文章的一开始大力推崇使用RowCoun的t方法,
可是由于原文中提供的方法不支持非unique字段的排序
大多场合都并不适用
文章末尾连作者自己提到,已经开始考虑改用cursor方法
可我对RowCount方法算是情有独中,于是对原文中该方法进行了改进
改进后的方法已基本上满足我的需要,现在发布出来,有用的朋友可以下载试用

修改记录:
    1)增加对非unique字段排序的支持,但必须设定一个PK字段(注:只要是unique字段都可以作为pk字段)
    2)增加记录总数输出参数
    3)修改原过程若干BUG
    4)修改PK字段只能是int型的bug(刚发现的,^_^)

注:
     1)如表名参数为多表连接时,sort列必须指定表名;
     2)只支持单字段排序,有朋友如果问为什么不做成可以多字段排序的,理论上确实有这种可能性,但需要以一定的效率损失为代价,而且会使方法过于复杂,如真有这种需要,完全可以写一个单独的分页存储过程,无论在性能还是复杂度上都比通用要简单.
     3)由于时间原因没有大量测试,如有BUG,请您提出,立刻修正;
     4)由于时间关系,只写了一个简单示例,需要的朋友可以下载
            分页示例
 

 

  1 if   exists  ( select   *   from  dbo.sysobjects  where  id  =   object_id (N ' [dbo].[Paging_RowCount] ' and   OBJECTPROPERTY (id, N ' IsProcedure ' =   1 )
  2 drop   procedure   [ dbo ] . [ Paging_RowCount ]
  3 GO
  4
  5 SET  QUOTED_IDENTIFIER  ON  
  6 GO
  7 SET  ANSI_NULLS  ON  
  8 GO
  9 -- -------------------------------------------------------------
 10 --  分页存储过程(使用RowCount)  --edit by SiBen
 11 --  summary:
 12 --           获取表或表集合的分页数据
 13 --           当多表连接时,sort列必须指定表名        
 14 -- -------------------------------------------------------------
 15
 16 CREATE   PROCEDURE  Paging_RowCount
 17 (
 18 @Tables   varchar ( 1000 ),
 19 @PK   varchar ( 100 ),
 20 @Sort   varchar ( 200 =   NULL ,
 21 @PageNumber   int   =   1 ,
 22 @PageSize   int   =   10 ,
 23 @Fields   varchar ( 1000 =   ' * ' ,
 24 @Filter   varchar ( 1000 =   NULL ,
 25 @Group   varchar ( 1000 =   NULL ,
 26 @RecordCount   int   =   0  output 
 27 )
 28 AS
 29
 30 /*Default Sorting*/
 31 IF   @Sort   IS   NULL   OR   @Sort   =   ''
 32      SET   @Sort   =   @PK
 33
 34 /*Find the @PK type*/
 35 DECLARE   @SortTable   varchar ( 100 )
 36 DECLARE   @SortName   varchar ( 100 )
 37 DECLARE   @PKTable   varchar ( 100 )
 38 DECLARE   @PKName   varchar ( 100 )
 39 DECLARE   @strSortColumn   varchar ( 200 )
 40 DECLARE   @operator   char ( 2 )
 41 DECLARE   @type   varchar ( 100 )
 42 DECLARE   @prec   int
 43
 44 /*Set sorting variables.*/     
 45 IF   CHARINDEX ( ' DESC ' , @Sort ) > 0
 46      BEGIN
 47          SET   @strSortColumn   =   REPLACE ( @Sort ' DESC ' '' )
 48          SET   @operator   =   ' < '
 49      END
 50 ELSE
 51      BEGIN
 52          IF   CHARINDEX ( ' ASC ' @Sort >   0
 53              SET   @strSortColumn   =   REPLACE ( @Sort ' ASC ' '' )
 54                  ELSE
 55                          SET   @strSortColumn   =   @Sort
 56
 57          SET   @operator   =   ' > '
 58      END
 59
 60 /* Set PK,Sort name */
 61 IF   CHARINDEX ( ' . ' @strSortColumn >   0
 62      BEGIN
 63          SET   @SortTable   =   SUBSTRING ( @strSortColumn 0 CHARINDEX ( ' . ' , @strSortColumn ))
 64          SET   @SortName   =   SUBSTRING ( @strSortColumn CHARINDEX ( ' . ' , @strSortColumn +   1 LEN ( @strSortColumn ))
 65      END
 66 ELSE
 67      BEGIN
 68          SET   @SortTable   =   @Tables
 69          SET   @SortName   =   @strSortColumn
 70      END
 71 IF   CHARINDEX ( ' . ' @PK >   0
 72      BEGIN
 73          SET   @PKTable   =   SUBSTRING ( @PK 0 CHARINDEX ( ' . ' , @PK ))
 74          SET   @PKName   =   SUBSTRING ( @PK CHARINDEX ( ' . ' , @PK +   1 LEN ( @PK ))
 75      END
 76 ELSE
 77      BEGIN
 78          SET   @PKTable   =   @Tables
 79          SET   @PKName   =   @PK
 80      END
 81
 82 SELECT   @type = t.name,  @prec = c.prec
 83 FROM  sysobjects o 
 84 JOIN  syscolumns c  on  o.id = c.id
 85 JOIN  systypes t  on  c.xusertype = t.xusertype
 86 WHERE  o.name  =   @SortTable   AND  c.name  =   @SortName
 87
 88 IF   CHARINDEX ( ' char ' @type >   0
 89     SET   @type   =   @type   +   ' ( '   +   CAST ( @prec   AS   varchar +   ' ) '
 90
 91 DECLARE   @strPageSize   varchar ( 50 )
 92 DECLARE   @strStartRow   varchar ( 50 )
 93 DECLARE   @strFilter   varchar ( 1000 )
 94 DECLARE   @strSimpleFilter   varchar ( 1000 )
 95 DECLARE   @strGroup   varchar ( 1000 )
 96
 97 /*Default Page Number*/
 98 IF   @PageNumber   <   1
 99      SET   @PageNumber   =   1
100
101 /*Set paging variables.*/
102 SET   @strPageSize   =   CAST ( @PageSize   AS   varchar ( 50 ))
103 SET   @strStartRow   =   CAST ((( @PageNumber   -   1 ) * @PageSize   +   1 AS   varchar ( 50 ))
104
105 /*Set filter & group variables.*/
106 IF   @Filter   IS   NOT   NULL   AND   @Filter   !=   ''
107      BEGIN
108          SET   @strFilter   =   '  WHERE  '   +   @Filter   +   '   '
109          SET   @strSimpleFilter   =   '  AND  '   +   @Filter   +   '   '
110      END
111 ELSE
112      BEGIN
113          SET   @strSimpleFilter   =   ''
114          SET   @strFilter   =   ''
115      END
116 IF   @Group   IS   NOT   NULL   AND   @Group   !=   ''
117      SET   @strGroup   =   '  GROUP BY  '   +   @Group   +   '   '
118 ELSE
119      SET   @strGroup   =   ''
120
121 /*Get rows count.*/
122 DECLARE   @str_Count_SQL   nvarchar ( 500 )
123 SET   @str_Count_SQL =   ' SELECT @TotalCount=count(*) FROM  '   +   @Tables   +   @strFilter
124 EXEC  sp_executesql  @str_Count_SQL ,N ' @TotalCount int=0 output ' , @RecordCount  output
125     
126 /*Execute dynamic query*/     
127 IF   @PKTable   =   @SortTable   and   @PKName   =   @SortName
128      BEGIN   
129          EXEC (
130          '
131         DECLARE @SortColumn  '   +   @type   +   '
132         SET ROWCOUNT  '   +   @strStartRow   +   '
133         SELECT @SortColumn= '   +   @strSortColumn   +   '  FROM  '   +   @Tables   +   @strFilter   +   '   '   +   @strGroup   +   '  ORDER BY  '   +   @Sort   +   '
134         SET ROWCOUNT  '   +   @strPageSize   +   '
135         SELECT  '   +   @Fields   +   '  FROM  '   +   @Tables   +   '  WHERE  '   +   @strSortColumn   +   @operator   +   ' = @SortColumn  '   +   @strSimpleFilter   +   '   '   +   @strGroup   +   '  ORDER BY  '   +   @Sort   +   '
136          '
137         )
138      END
139 ELSE
140      BEGIN
141                  /* Get PK Type */
142          DECLARE   @pktype   varchar ( 100 )
143                  DECLARE   @pkprec   int
144         
145          SELECT   @pktype = t.name,  @pkprec = c.prec
146          FROM  sysobjects o 
147          JOIN  syscolumns c  on  o.id = c.id
148          JOIN  systypes t  on  c.xusertype = t.xusertype
149          WHERE  o.name  =   @PKTable   AND  c.name  =   @PKName
150
151          IF   CHARINDEX ( ' char ' @pktype >   0
152             SET   @pktype   =   @pktype   +   ' ( '   +   CAST ( @pkprec   AS   varchar +   ' ) '
153
154                  /*Execute dynamic query*/     
155          EXEC (
156          '
157         DECLARE @SortColumn  '   +   @type   +   '
158         DECLARE @SortNullValue  '   +   @type   +   '
159         DECLARE @PKStartValue  '   +   @pktype   +   '
160         SET @SortNullValue=CAST( ''''  as  ' +   @type   + ' )
161         SET ROWCOUNT  '   +   @strStartRow   +   '
162         SELECT @SortColumn= isNull( '   +   @strSortColumn   +   ' ,@SortNullValue), @PKStartValue =  ' +   @PK   + '  FROM  '   +   @Tables   +   @strFilter   +   '   '   +   @strGroup   +   '  ORDER BY  '   +   @Sort   +   ' , ' +   @PK   + '  Desc 
163         SET ROWCOUNT  '   +   @strPageSize   +   '
164         SELECT  '   +   @Fields   +   '  FROM  '   +   @Tables   +   '  WHERE (isNull( '   +   @strSortColumn + ' ,@SortNullValue) '   +   @operator   +   '  @SortColumn or (isNull( '   +   @strSortColumn + ' ,@SortNullValue)=@SortColumn and  ' +   @PK   + ' <=@PKStartValue)) '   +   @strSimpleFilter   +   '   '   +   @strGroup   +   '  ORDER BY  '   +   @Sort   +   ' , ' +   @PK   + '  Desc
165          '
166         )
167      END
168 GO
169 SET  QUOTED_IDENTIFIER  OFF  
170 GO
171 SET  ANSI_NULLS  ON  
172 GO
173
174
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值