经验首页 前端设计 程序设计 Java相关 移动开发 数据库/运维 软件/图像 大数据/云计算 其他经验
当前位置:技术经验 » 数据库/运维 » MS SQL Server » 查看文章
【干货】SqlServer 总结几种存储过程分页的使用 - 熊泽-学习中的苦与乐
来源:cnblogs  作者:熊泽-学习中的苦与乐  时间:2019/5/14 8:47:16  对本文有异议

就我而言写代码最烦的就是处理数据,其中之一就是分页的使用。

有的代码写多了,总结出一套适用自己的分页方法;有的查一下资料借鉴一下套用起来也达到目的。

那么小编在这里给大家总结几个方法供大家做一下参考。

分页方法一:

  1. SET ANSI_NULLS ON
  2. GO
  3. SET QUOTED_IDENTIFIER ON
  4. GO/*********************************************************
  5. * 作 用:数据分页
  6. * 作 者:Ozawa
  7. * 作者博客:https://www.cnblogs.com/xiongze520/
  8. * 创建日期:2019-05-13
  9. * 使用说明:
  10. --调用例子:
  11. --1.单表/单排序
  12. EXEC proc_DataPagination @TableNames='bigtable',@PrimaryKey='d_id',@Fields='d_id,d_title,d_content,d_time',@PageSize=20,@CurrentPage=1,@Filter ='',@Group='',@Order='d_id desc'
  13. --2.单表/多排序
  14. EXEC proc_DataPagination 'bigtable','d_id','*',20,0,'','','d_time asc,d_id desc'
  15. --3.多表/单排序
  16. EXEC proc_DataPagination 'bigtable left join bigtable_author on bigtable.d_id=bigtable_author.BigTable_id', 'bigtable.d_id', 'bigtable.d_id,bigtable.d_title,bigtable.d_content,bigtable.d_time,bigtable_author.d_author', 20, 0, '', '', 'bigtable.d_id asc'
  17. --4.多表/多排序
  18. EXEC proc_DataPagination 'bigtable left join bigtable_author on bigtable.d_id=bigtable_author.BigTable_id', 'bigtable.d_id', 'bigtable.d_id,bigtable.d_title,bigtable.d_content,bigtable.d_time,bigtable_author.d_author', 20, 0, '', '', 'bigtable.d_time asc,bigtable.d_id desc'
  19. *********************************************************/
  20. CREATE PROCEDURE [dbo].[proc_DataPagination]
  21. @TableNames VARCHAR(200), --表名,可以是多个表,但不能用别名
  22. @PrimaryKey VARCHAR(100), --主键,可以为空,但@Order为空时该值不能为空
  23. @Fields VARCHAR(200), --要取出的字段,可以是多个表的字段,可以为空,为空表示select *
  24. @PageSize INT, --每页记录数
  25. @CurrentPage INT, --当前页,0表示第1
  26. @Filter VARCHAR(200) = '', --条件,可以为空,不用填 where
  27. @Group VARCHAR(200) = '', --分组依据,可以为空,不用填 group by
  28. @Order VARCHAR(200) = '' --排序,可以为空,为空默认按主键升序排列,不用填 order by
  29. AS
  30. BEGIN
  31. DECLARE @SortColumn VARCHAR(200)
  32. DECLARE @Operator CHAR(2)
  33. DECLARE @SortTable VARCHAR(200)
  34. DECLARE @SortName VARCHAR(200)
  35. IF @Fields = ''
  36. SET @Fields = '*'
  37. IF @Filter = ''
  38. SET @Filter = 'WHERE 1=1'
  39. ELSE
  40. SET @Filter = 'WHERE ' + @Filter
  41. IF @Group <>''
  42. SET @Group = 'GROUP BY ' + @Group
  43. IF @Order <> ''
  44. BEGIN
  45. DECLARE @pos1 INT, @pos2 INT
  46. SET @Order = REPLACE(REPLACE(@Order, ' asc', ' ASC'), ' desc', ' DESC')
  47. IF CHARINDEX(' DESC', @Order) > 0
  48. IF CHARINDEX(' ASC', @Order) > 0
  49. BEGIN
  50. IF CHARINDEX(' DESC', @Order) < CHARINDEX(' ASC', @Order)
  51. SET @Operator = '<='
  52. ELSE
  53. SET @Operator = '>='
  54. END
  55. ELSE
  56. SET @Operator = '<='
  57. ELSE
  58. SET @Operator = '>='
  59. SET @SortColumn = REPLACE(REPLACE(REPLACE(@Order, ' ASC', ''), ' DESC', ''), ' ', '')
  60. SET @pos1 = CHARINDEX(',', @SortColumn)
  61. IF @pos1 > 0
  62. SET @SortColumn = SUBSTRING(@SortColumn, 1, @pos1-1)
  63. SET @pos2 = CHARINDEX('.', @SortColumn)
  64. IF @pos2 > 0
  65. BEGIN
  66. SET @SortTable = SUBSTRING(@SortColumn, 1, @pos2-1)
  67. IF @pos1 > 0
  68. SET @SortName = SUBSTRING(@SortColumn, @pos2+1, @pos1-@pos2-1)
  69. ELSE
  70. SET @SortName = SUBSTRING(@SortColumn, @pos2+1, LEN(@SortColumn)-@pos2)
  71. END
  72. ELSE
  73. BEGIN
  74. SET @SortTable = @TableNames
  75. SET @SortName = @SortColumn
  76. END
  77. END
  78. ELSE
  79. BEGIN
  80. SET @SortColumn = @PrimaryKey
  81. SET @SortTable = @TableNames
  82. SET @SortName = @SortColumn
  83. SET @Order = @SortColumn
  84. SET @Operator = '>='
  85. END
  86. DECLARE @type varchar(50)
  87. DECLARE @prec int
  88. SELECT @type=t.name, @prec=c.prec
  89. FROM sysobjects o
  90. JOIN syscolumns c on o.id=c.id
  91. JOIN systypes t on c.xusertype=t.xusertype
  92. WHERE o.name = @SortTable AND c.name = @SortName
  93. IF CHARINDEX('char', @type) > 0
  94. SET @type = @type + '(' + CAST(@prec AS varchar) + ')'
  95. DECLARE @TopRows INT
  96. SET @TopRows = @PageSize * @CurrentPage + 1
  97. print @TopRows
  98. print @Operator
  99. EXEC('
  100. DECLARE @SortColumnBegin ' + @type + '
  101. SET ROWCOUNT ' + @TopRows + '
  102. SELECT @SortColumnBegin=' + @SortColumn + ' FROM ' + @TableNames + ' ' + @Filter + ' ' + @Group + ' ORDER BY ' + @Order + '
  103. SET ROWCOUNT ' + @PageSize + '
  104. SELECT ' + @Fields + ' FROM ' + @TableNames + ' ' + @Filter + ' AND ' + @SortColumn + '' + @Operator + '@SortColumnBegin ' + @Group + ' ORDER BY ' + @Order + '
  105. ')
  106. END
  107. GO

 

方法二:

  1. /*********************************************************
  2. * 作 用:数据分页
  3. * 作 者:Ozawa
  4. * 作者博客:https://www.cnblogs.com/xiongze520/
  5. * 创建日期:2019-05-13
  6. * 使用说明:
  1.       declare @pageCount int
  2.       exec commonPagination  'job_id,job_desc','jobs','job_id', 'asc','1=1',2,2,@pageCount output
  3.       --select '总页数为:' + str(@pageCount)
  1. *********************************************************/

  1. CREATE PROCEDURE commonPagination
  2. @columns varchar(500), --要显示的列名,用逗号隔开
  3. @tableName varchar(100), --要查询的表名
  4. @orderColumnName varchar(100), --排序的列名
  5. @order varchar(50), --排序的方式,升序为asc,降序为 desc
  6. @where varchar(100), --where 条件,如果不带查询条件,请用 1=1
  7. @pageIndex int, --当前页索引
  8. @pageSize int, --页大小(每页显示的记录条数)
  9. @pageCount int --总页数,输出参数
  10. as
  11. begin
  12. declare @sqlRecordCount nvarchar(1000) --得到总记录条数的语句
  13. declare @sqlSelect nvarchar(1000) --查询语句
  14. set @sqlRecordCount=N'select @recordCount=count(*) from ' +@tableName + ' where '+ @where
  15. declare @recordCount int --保存总记录条数的变量
  16. exec sp_executesql @sqlRecordCount,N'@recordCount int output',@recordCount output
  17. --动态 sql 传参
  18. if( @recordCount % @pageSize = 0) --如果总记录条数可以被页大小整除
  19. set @pageCount = @recordCount / @pageSize --总页数就等于总记录条数除以页大小
  20. else --如果总记录条数不能被页大小整除
  21. set @pageCount = @recordCount / @pageSize + 1 --总页数就等于总记录条数除以页大小加1
  22. set @sqlSelect =
  23. N'select '+@columns+' from (
  24. select row_number() over (order by '
  25. +@orderColumnName+' '+@order
  26. +') as tempid,* from '
  27. +@tableName+' where '+ @where
  28. +') as tempTableName where tempid between '
  29. +str((@pageIndex - 1)*@pageSize + 1 )
  30. +' and '+str( @pageIndex * @pageSize)
  31. exec (@sqlSelect) --执行动态Sql
  32. end

 

方法三:

  1. create PROCEDURE commonPagination
  2. (@TableName VARCHAR(2000), --表名
  3. @ReFieldsStr VARCHAR(1000) = '*', --字段名(全部字段为*)
  4. @OrderString VARCHAR(200), --排序字段(必须!支持多字段不用加order by)
  5. @WhereString VARCHAR(500) = N'', --条件语句(不用加where)
  6. @PageSize INT, --每页多少条记录
  7. @PageIndex INT = 1, --指定当前为第几页
  8. @TotalRecord INT OUTPUT --返回总记录数
  9. )
  10. AS
  11. BEGIN
  12. --处理开始点和结束点
  13. DECLARE @StartRecord INT;
  14. DECLARE @EndRecord INT;
  15. DECLARE @TotalCountSql NVARCHAR(500);
  16. DECLARE @SqlString NVARCHAR(2000);
  17. SET @StartRecord = (@PageIndex - 1) * @PageSize + 1;
  18. SET @EndRecord = @StartRecord + @PageSize - 1;
  19. SET @TotalCountSql = N'select @TotalRecord = count(*) from '+@TableName;--总记录数语句
  20. SET @SqlString = N'(select row_number() over (order by '+@OrderString+') as rowId,'+@ReFieldsStr+' from '+@TableName;--查询语句
  21. -- 判断条件是否为空
  22. IF(@WhereString != ''
  23. OR @WhereString != NULL)
  24. BEGIN
  25. SET @TotalCountSql = @TotalCountSql+' where '+@WhereString;
  26. SET @SqlString = @SqlString+' where '+@WhereString;
  27. END;
  28. --返回总记录数
  29. EXEC sp_executesql
  30. @totalCountSql,
  31. N'@TotalRecord int out',
  32. @TotalRecord OUTPUT;
  33. ----执行主语句
  34. SET @SqlString = 'select * from '+@SqlString+') as t where rowId between '+LTRIM(STR(@StartRecord))+' and '+LTRIM(STR(@EndRecord));
  35. EXEC (@SqlString);
  36. END;

 

方式四:

  1. /*********************************************************
  2. * 作 用:数据分页
  3. * 作 者:Ozawa
  4. * 作者博客:https://www.cnblogs.com/xiongze520/
  5. * 创建日期:2019-05-13
  6. * 使用说明:
  1.       [USP_GetPageData] 'select * from 表名',1,10
  1.  
  1. *********************************************************/

  1. CREATE PROCEDURE [dbo].[USP_GetPageData]
  2. (
  3. @SQLSTR VARCHAR(8000) -- 查询的SQL语句
  4. , @CURPAGE INT -- 当前页面位置
  5. , @PAGESIZE INT -- 页面显示的数据行数
  6. )
  7. AS
  8. BEGIN
  9. SET NOCOUNT ON
  10. DECLARE @P1 INT --游标
  11. , @ROWCOUNT INT
  12. , @COUNTPAGE INT
  13. , @CurRow INT
  14. EXEC sp_cursoropen @P1 OUTPUT, @SQLSTR, @scrollopt = 1, @ccopt = 1, @ROWCOUNT = @ROWCOUNT OUTPUT
  15. IF @ROWCOUNT % @PAGESIZE > 0
  16. SET @COUNTPAGE = @ROWCOUNT / @PAGESIZE + 1
  17. ELSE
  18. SET @COUNTPAGE = @ROWCOUNT / @PAGESIZE
  19. IF @CURPAGE > @COUNTPAGE
  20. SET @CURPAGE = @COUNTPAGE
  21. SET @CurRow = (@CURPAGE - 1) * @PAGESIZE + 1
  22. SET NOCOUNT OFF
  23. SELECT @CURPAGE CURPAEG, @PAGESIZE PageSize, @COUNTPAGE COUNTPAGE, @ROWCOUNT [ROWCOUNT]
  24. EXEC sp_cursorfetch @P1, 16, @CurRow, @PAGESIZE
  25. SET NOCOUNT ON
  26. EXEC sp_cursorclose @P1
  27. END

 

还有更多分页方式,感兴趣的可以去查查资料,上面的分页方式已经足够参考了,

然后结合自身情况可以写一个量身定做的分页方法,后续直接使用就可以了。

 

原文链接:http://www.cnblogs.com/xiongze520/p/10855312.html

 友情链接:直通硅谷  点职佳  北美留学生论坛

本站QQ群:前端 618073944 | Java 606181507 | Python 626812652 | C/C++ 612253063 | 微信 634508462 | 苹果 692586424 | C#/.net 182808419 | PHP 305140648 | 运维 608723728

W3xue 的所有内容仅供测试,对任何法律问题及风险不承担任何责任。通过使用本站内容随之而来的风险与本站无关。
关于我们  |  意见建议  |  捐助我们  |  报错有奖  |  广告合作、友情链接(目前9元/月)请联系QQ:27243702 沸活量
皖ICP备17017327号-2 皖公网安备34020702000426号