首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > 数据库 > SQL Server >

求SQL SERVER 2005高效分页存储过程(row_number版本)解决方法

2012-03-19 
求SQL SERVER 2005高效分页存储过程(row_number版本)现在在用的一个是使用TOP方法的通用分页存储过程,据说

求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 '+@strColumn+') t) ORDER BY '+ @strColumn    ELSE              --构造降序的SQL         SET @sql='SELECT TOP '+ CAST(@intPageSize   AS   varchar) +                @strColumnlist+                  ' FROM '+ @strTable + @where1 +                @strColumn + '<(SELECT   MIN('+@strColumn+')   '+                  ' FROM (SELECT TOP '+ CAST(@intPageSize*(@intPageNum - 1) AS  varchar) +                  @strColumn + ' FROM '+ @strTable+@where2+'ORDER   BY '+@strColumn+'   DESC)   t)   ORDER   BY   '+                  @strColumn + ' DESC'         IF   @intPageNum=1--第一页         SET   @sql='SELECT   TOP   '+CAST(@intPageSize   AS   varchar) + @strColumnlist + ' FROM '+@strTable+                    @where2+'ORDER   BY   '+@strColumn+CASE   @intOrder WHEN  0 THEN  '' ELSE  ' DESC'  END    --PRINT   @sql    EXEC(@sql)    GO 


[解决办法]
据说2011里面有个更好的办法
[解决办法]
SQL2005分页查询 
几种方式比较
http://blog.csdn.net/xuexiaodong2009/archive/2011/04/20/6336638.aspx
[解决办法]

探讨
我看到一种写法是说避免操作所有的记录以提高查询性能。
而这给出的row_number方法是操作了所有的记录的,据说这个不是很好的性能?
是这样么?

继续求高手指点。

[解决办法]
我提供两种方法,是我以前写的,也许对你有用
1. 批处理实现
SQL code
/**************************************************    功能描述:数据分页技术的实现    程序编码: 刘永涛    创建日期:2008.09.23    修改记录:    参考资料:无**************************************************/declare @i_PageRow int, @i_Page Int, @i_PageCount Int, @i_PageSum Int, @Str_Sql NVarchar(1000)Set @i_PageRow = 10Select @i_Page = Count(*) From Base_CodeMSet @i_Page = (@i_Page / @i_PageRow) + 1Set @i_PageCount = 0Select @i_Page, @i_PageSumWhile @i_PageCount < @i_PageBegin    Set @i_PageSum = @i_PageCount * @i_PageRow    Set @Str_Sql = 'Select Top ' + Cast(@i_PageRow As Varchar(10)) + ' * From Base_CodeM Where CodeID > '        + 'All(Select Top ' + Cast(@i_PageSum As Varchar(10)) + ' CodeID From Base_CodeM Order By CodeID) Order By CodeID'    Exec(@Str_Sql)Print @Str_Sql    Set @i_PageCount = @i_PageCount + 1End 

热点排行
Bad Request.