关于通用分页存储过程讨论
前段时间帮朋友写一个通用的存储过程,在网上看了很多相关代码。基本都是构造一个查询串,然后将需要查找的数据编号储存到临时表中,然后在临时表中取数据。下面是典型的代码:
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几秒针