日期:2014-05-18  浏览次数:20508 次

关于通用分页存储过程讨论
前段时间帮朋友写一个通用的存储过程,在网上看了很多相关代码。基本都是构造一个查询串,然后将需要查找的数据编号储存到临时表中,然后在临时表中取数据。下面是典型的代码:
CREATE   PROC   sp_PageIndex
  @sqlSelect   varchar(800)   --SELECT   后面   FROM   前面   的   字段   不用包含SELECT
,@sqlFrom   varchar(800)   --FROM   后面   的   字段   包含FROM
,@countPerPage   int   --   每页数据行数
,@toPage   int   --要转到的页码

AS

BEGIN  

--   根据每页数据行数   和   要转到的页码   得到   数据起止点
Declare   @start   int
Declare   @end   int

set   @end   =   @countPerPage   *   @toPage
set   @start   =   @countPerPage   *   (@toPage   -   1)   +   1  


--   临时表名称   可随机命名
Declare   @tmpTable   varchar(10)
SET   @tmpTable   = '#tmp '

Declare   @sqlStr   varchar(800)
--   创建数据源到临时表
SELECT   @sqlStr   =   'SELECT   Identity(int,1,1)   AS   RowIndex, '
SELECT   @sqlStr   =   @sqlStr   +   rtrim(@sqlSelect)   +   '   INTO     '+   @tmpTable  
SELECT   @sqlStr   =   @sqlStr   +   rtrim(@sqlFrom)  
--   查询临时表   得到所需要的数据
SELECT   @sqlStr   =   @sqlStr   +   '   '+ 'SELECT   '+   rtrim(@sqlSelect)   + '   FROM   '   +   @tmpTable  
SELECT   @sqlStr   =   @sqlStr   +   '   WHERE     RowIndex   BETWEEN   '   +   Convert(char,@start)   +   "   AND   "   +   Convert(char,@end)
--   删除临时表
SELECT   @sqlStr   =   @sqlStr   +   '   '+ 'DROP   TABLE   '+@tmpTable
EXEC   (@sqlStr)  

这样做先不说性能方面,就数据查询方面还是有很多问题的。比如说用@sqlSelect保存查询串,可是在查询串中,列不能带表名,也不能带别名。这对查询的适应性就太差了。大家都有什么好的解决办法呢??(SQL   2000数据库下,无row_number函数)

------解决方案--------------------
并且会导致查询不会命中索引,我特意对排序字段进行了索引,用普通的排序查询语句可以命中,150多万数据,查询只要几百毫秒,但用row_number,则需要10几秒针