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

求SQL SERVER 2005高效分页存储过程(row_number版本)
现在在用的一个是使用TOP方法的通用分页存储过程,据说是俄罗斯版本的。效果也不错,现在用SQL server2005数据库了,据说row_number函数版本的效率更好?是这样么?

我到网上查了查,发现写法很多,看的头昏也不知到底哪一个版本才是真正的使用了ROW_NUMBER的优势。请各位大侠推荐一个公认的高效row_number分页方法。

谢谢

------解决方案--------------------
-- =============================================
-- 使用RowNumber分页
-- 参数
-- {
-- @SQL : 查询语句
-- @Order : 排序字段
-- @CurPage : 当前页
-- @PageRows : 每页大小
-- @TotalRecorder : 记录总数
-- }
-- =============================================
CREATE PROCEDURE [dbo].[up_DataPageRowNumber]
-- Add the parameters for the stored procedure here
@SQL Nvarchar(2000),
@Order Nvarchar(20),
@PageIndex int,
@PageSize int,
@TotalRecorder int output
AS
BEGIN
-- SET NOCOUNT ON added to prevent extra result sets from
SET NOCOUNT ON;
declare @ExceSQL nvarchar(4000)


--设置开始行号
declare @start_row_num AS int
SET @start_row_num = (@PageIndex - 1) * @PageSize + 1
--设置结束行号
declare @end_row_num int
set @end_row_num = @PageIndex * @PageSize
 
--设置标识语句
declare @RowNumber nvarchar(100)
set @RowNumber = ', ROW_NUMBER() OVER(ORDER BY ' + @Order + ') as RowNumber from '

set @SQL = Replace(@SQL,' from ',@RowNumber)

--获取记录总数
set @ExceSQL = 'select @TotalRecorder=max(RowNumber) from (' + @SQL + ') as tmp'

execute sp_executesql @ExceSQL,N'@TotalRecorder int output',@TotalRecorder output

--设置查询语句
set @ExceSQL = 'select * from (' + @SQL + ') as tmp where RowNumber between ' + Convert(nvarchar,@start_row_num)
+ ' And ' + Convert(nvarchar, @end_row_num)

execute(@ExceSQL)

END
GO

------解决方案--------------------
SQL code
CREATE   PROCEDURE   sp_page   
    @strTable       varchar(50),   --表名   
    @strColumn      varchar(50),   --按该列来进行分页   
    @intColType     int,           --@strColumn列的类型,0-数字类型,1-字符类型,2-日期时间类型   
    @intOrder       bit,           --排序,0-顺序,1-倒序   
    @strColumnlist varchar(800), --要查询出的字段列表,*表示全部字段   
    @intPageSize    int,           --每页记录数   
    @intPageNum     int,           --指定页   
    @strWhere       varchar(800), --查询条件   
    @intPageCount   int   OUTPUT   --总页数   
 AS   
  DECLARE   @sql    nvarchar(4000) --用于构造SQL语句
 DECLARE   @where1 varchar(800)   --构造条件语句
 DECLARE   @where2 varchar(800)   --构造条件语句
 IF   @strWhere   is   null   or   rtrim(@strWhere)=''   
 -- 为了避免SQL关键字与字段、表名等连在一起,首先为传入的变量添加空格
 BEGIN  --没有查询条件   
      SET   @where1=' WHERE '   
      SET   @where2=' '   
 END   
 ELSE   
 BEGIN  --有查询条件   
      SET   @where1=' WHERE ('+@strWhere+') AND ' 
      SET   @where2=' WHERE ('+@strWhere+') '   
 END   
  set @strColumn = ' ' + @strColumn + ' '
 set @strColumnlist = ' ' + @strColumnlist + ' '
 --构造SQL语句,计算总页数。计算公式为 总页数 = Ceiling ( 记录个数 / 页大小 )
 SET   @sql='SELECT   @intPageCount=CEILING((COUNT(*)+0.0)/'
        + CAST(@intPageSize   AS   varchar)
        + ')   FROM   ' + @strTable + @where2   
 --执行SQL语句,计算总页数,并将其放入@intPageCount变量中
 EXEC sp_executesql @sql,N'@intPageCount   int   OUTPUT',@intPageCount   OUTPUT 
 --将总页数放到查询返回记录集的第一个字段前,此语句可省略
 SET  @strColumnlist= Cast(@intPageCount as varchar(30)) + ' as PageCount,' + @strColumnlist   
 IF   @intOrder=0   --构造升序的SQL
      SET @sql='SELECT TOP '+ CAST(@intPageSize   AS   varchar) + 
               @strColumnlist +   
               ' FROM ' + @strTable + @where1 + 
               @strColumn + '>(SELECT MAX('+@strColumn+') '+   
               ' FROM (SELECT TOP '+ CAST(@intPageSize*(@intPageNum - 1) AS  varchar) +   
               @strColumn + ' FROM '+ @strTable+@where2+'ORDER BY '