SQL 存储过程[3] - 分页
SQL 存储过程[3]-分页
示例1:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 | /* 分页,统计 */ CREATE PROCEDURE Page @tblName varchar (255), -- 表名 @fldName varchar (255), -- 字段名 @PageSize int = 10, -- 页尺寸 @PageIndex int = 1, -- 页码 @IsCount bit = 0, -- 返回记录总数, 非 0 值则返回 @OrderType bit = 0, -- 设置排序类型, 非 0 值则降序 @strWhere varchar (1000) = '' , -- 查询条件 (注意: 不要加 where) @FieldsList varchar (255) -- 字段列表(要选出的字段) AS declare @strSQL varchar (1000), -- 主语句 @strTmp varchar (300), -- 临时变量 @strOrder varchar (400) -- 排序类型 set @strTmp = '' set @strOrder = '' --只统计总记录数 if @IsCount != 0 begin if @strWhere != '' set @strTmp = " where (" + @strWhere + ")" set @strSQL = "select count(*) as Total from [" + @tblName + "]" + @strTmp end --不统计总记录,分页(查询表中所有记录) else begin --如果是第一页 if @PageIndex = 1 begin --排序 if @OrderType != 0 set @strOrder = " order by [" + @fldName + "] desc" else set @strOrder = " order by [" + @fldName + "] asc" --条件 if @strWhere != '' set @strTmp = " where (" + @strWhere + ")" set @strSQL = "select top " + str(@PageSize) + " " +@FieldsList + " from [" + @tblName + "]" + @strTmp + " " + @strOrder end --如果不是第一页 else begin --排序 if @OrderType != 0 begin set @strTmp = "<(select min" set @strOrder = " order by [" + @fldName + "] desc" end else begin set @strTmp = ">(select max" set @strOrder = " order by [" + @fldName + "] asc" end set @strSQL = "select top " + str(@PageSize) + " " + @FieldsList + " from [" + @tblName + "] where [" + @fldName + "]" + @strTmp + "([" + @fldName + "]) from (select top " + str((@PageIndex-1)*@PageSize) + " [" + @fldName + "] from [" + @tblName + "]" + @strOrder + ") as tblTmp)" + @strOrder --条件 if @strWhere != '' set @strSQL = "select top " + str(@PageSize) + " " + @FieldsList + " from [" + @tblName + "] where [" + @fldName + "]" + @strTmp + "([" + @fldName + "]) from (select top " + str((@PageIndex-1)*@PageSize) + " [" + @fldName + "] from [" + @tblName + "] where (" + @strWhere + ") " + @strOrder + ") as tblTmp) and (" + @strWhere + ") " + @strOrder end end exec (@strSQL) |
示例2:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 | CREATE PROCEDURE Rperp_Page_Data_GetList @tbname sysname, --要分页显示的表名 @FieldKey sysname, --用于定位记录的主键(惟一键)字段,只能是单个字段 @PageCurrent int =1, --要显示的页码 @PageSize int =10, --每页的大小(记录数) @FieldShow nvarchar(1000)= '' , --以逗号分隔的要显示的字段列表,如果不指定,则显示所有字段 @FieldOrder nvarchar(1000)= '' , --以逗号分隔的排序字段列表,可以指定在字段后面指定DESC/ASC用于指定排序顺序 @ Where nvarchar(1000)= '' , --查询条件 @pagecount int output , @ count int output AS DECLARE @sql nvarchar(4000) SET NOCOUNT ON --检查对象是否有效 IF OBJECT_ID(@tbname) IS NULL BEGIN RAISERROR(N '对象"%s"不存在' ,1,16,@tbname) RETURN END IF OBJECTPROPERTY(OBJECT_ID(@tbname),N 'IsTable' )=0 AND OBJECTPROPERTY(OBJECT_ID(@tbname),N 'IsView' )=0 AND OBJECTPROPERTY(OBJECT_ID(@tbname),N 'IsTableFunction' )=0 BEGIN RAISERROR(N '"%s"不是表、视图或者表值函数' ,1,16,@tbname) RETURN END --分页字段检查 IF ISNULL (@FieldKey,N '' )= '' BEGIN RAISERROR(N '分页处理需要主键(或者惟一键)' ,1,16) RETURN END --其他参数检查及规范 IF ISNULL (@PageCurrent,0)<1 SET @PageCurrent=1 IF ISNULL (@PageSize,0)<1 SET @PageSize=10 IF ISNULL (@FieldShow,N '' )=N '' SET @FieldShow=N '*' IF ISNULL (@FieldOrder,N '' )=N '' SET @FieldOrder=N '' ELSE SET @FieldOrder=N 'ORDER BY ' +LTRIM(@FieldOrder) IF ISNULL (@ Where ,N '' )=N '' SET @ Where =N '' ELSE SET @ Where =N 'WHERE ' +@ Where --如果@PageCount为NULL值,则计算总页数(这样设计可以只在第一次计算总页数,以后调用时,把总页数传回给存储过程,避免再次计算总页数,对于不想计算总页数的处理而言,可以给@PageCount赋值) IF @PageCount IS NULL BEGIN SET @sql=N 'SELECT @PageCount=COUNT(*)' +N ' FROM ' +@tbname +N ' ' +@ Where EXEC sp_executesql @sql,N '@PageCount int OUTPUT' ,@PageCount OUTPUT SET @ count =@PageCount SET @PageCount=(@PageCount+@PageSize-1)/@PageSize END --计算分页显示的TOPN值 DECLARE @TopN varchar (20),@TopN1 varchar (20) SELECT @TopN=@PageSize, @TopN1=@PageCurrent*@PageSize --第一页直接显示 IF @PageCurrent=1 EXEC (N 'SELECT TOP ' +@TopN +N ' ' +@FieldShow +N ' FROM ' +@tbname +N ' ' +@ Where +N ' ' +@FieldOrder) ELSE BEGIN SELECT @PageCurrent=@TopN1, @sql=N 'SELECT @n=@n-1,@s=CASE WHEN @n<' +@TopN +N ' THEN @s+N' ',' '+QUOTENAME(RTRIM(CAST(' +@FieldKey +N ' as varchar(8000))),N' '' '' '' ') ELSE N' '' ' END FROM ' +@tbname +N ' ' +@ Where +N ' ' +@FieldOrder SET ROWCOUNT @PageCurrent EXEC sp_executesql @sql, N '@n int,@s nvarchar(4000) OUTPUT' , @PageCurrent,@sql OUTPUT SET ROWCOUNT 0 IF @sql=N '' EXEC (N 'SELECT TOP 0' +N ' ' +@FieldShow +N ' FROM ' +@tbname) ELSE BEGIN SET @sql=STUFF(@sql,1,1,N '' ) --执行查询 EXEC (N 'SELECT TOP ' +@TopN +N ' ' +@FieldShow +N ' FROM ' +@tbname +N ' WHERE ' +@FieldKey +N ' IN(' +@sql +N ') ' +@FieldOrder) END END GO |
示例3:带偏移量的适合首页数据、非首页、不带偏移量等
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 | USE Hotel go --带偏移量的适合首页数据的存储过程 CREATE PROC PaginationWithOffsetInFirstPage @columns VARCHAR (500) , --要显示的列名,用逗号隔开 @tableName VARCHAR (100) , --要查询的表名 @orderColumnName VARCHAR (100) , --排序的列名 @ order VARCHAR (50) , --排序的方式,升序为asc,降序为 desc @ where VARCHAR (100) , --where 条件,如果不带查询条件,请用 1=1 @pageIndex INT , --当前页索引 @pageSize INT , --页大小(每页显示的记录条数) @offset INT , --偏移量(页中如果有别的数据需要插入,就赋此参数) @pageCount INT OUTPUT , --总页数,输出参数 @totalCount INT OUTPUT --总记录数,输出参数 AS BEGIN DECLARE @sqlRecordCount NVARCHAR(1000) --得到总记录条数的语句 DECLARE @sqlSelect NVARCHAR(1000) --查询语句 SET @sqlRecordCount = N 'select @recordCount=count(*) from ' + @tableName + ' where ' + @ where DECLARE @recordCount INT --保存总记录条数的变量 EXEC sp_executesql @sqlRecordCount, N '@recordCount int output' , @recordCount OUTPUT --动态 sql 传参 SET @totalCount = @recordCount --把总记录数赋给输出参数 IF ( @recordCount % @pageSize = 0 ) --如果总记录条数可以被页大小整除 SET @pageCount = @recordCount / @pageSize --总页数就等于总记录条数除以页大小 ELSE --如果总记录条数不能被页大小整除 SET @pageCount = @recordCount / @pageSize + 1 --总页数就等于总记录条数除以页大小加1 SET @sqlSelect = N 'select top' + STR(@pageSize - @offset) + @columns + ' from ( select row_number() over (order by ' + @orderColumnName + ' ' + @ order + ') as rowId,* from ' + @tableName + ' where ' + @ where + ') as A where A.rowId >' + STR(( @pageindex - 1 ) * @pageSize) --STR(( @pageIndex - 1 )* @pageSize + 1) + ' and ' --+ STR(@pageIndex * @pageSize) EXEC (@sqlSelect) --执行动态Sql END go --以下是调用示例 USE Hotel go CREATE PROC PaginationWithOffsetNotInFirstPage @columns VARCHAR (500) , --要显示的列名,用逗号隔开 @tableName VARCHAR (100) , --要查询的表名 @orderColumnName VARCHAR (100) , --排序的列名 @ order VARCHAR (50) , --排序的方式,升序为asc,降序为 desc @ where VARCHAR (100) , --where 条件,如果不带查询条件,请用 1=1 @pageIndex INT , --当前页索引 @pageSize INT , --页大小(每页显示的记录条数) @offset INT , --偏移量(页中如果有别的数据需要插入,就赋此参数,默认为零) @pageCount INT OUTPUT , --总页数,输出参数 @totalCount INT OUTPUT --总记录数,输出参数 AS BEGIN DECLARE @sqlRecordCount NVARCHAR(1000) --得到总记录条数的语句 DECLARE @sqlSelect NVARCHAR(1000) --查询语句 SET @sqlRecordCount = N 'select @recordCount=count(*) from ' + @tableName + ' where ' + @ where DECLARE @recordCount INT --保存总记录条数的变量 EXEC sp_executesql @sqlRecordCount, N '@recordCount int output' , @recordCount OUTPUT --动态 sql 传参 SET @totalCount = @recordCount --把总记录数赋给输出参数 IF ( @recordCount % @pageSize = 0 ) --如果总记录条数可以被页大小整除 SET @pageCount = @recordCount / @pageSize --总页数就等于总记录条数除以页大小 ELSE --如果总记录条数不能被页大小整除 SET @pageCount = @recordCount / @pageSize + 1 --总页数就等于总记录条数除以页大小加1 SET @sqlSelect = N 'select top' + STR(@pageSize) + @columns + ' from ( select row_number() over (order by ' + @orderColumnName + ' ' + @ order + ') as rowId,* from ' + @tableName + ' where ' + @ where + ') as A where A.rowId >' + STR(( @pageindex - 1 ) * @pageSize - @offset) --STR(( @pageIndex - 1 )* @pageSize + 1) + ' and ' --+ STR(@pageIndex * @pageSize) EXEC (@sqlSelect) --执行动态Sql END go USE Hotel go --调用首页数据的存储过程,page必须传1 DECLARE @d DATETIME SET @d = GETDATE() DECLARE @pageCount INT DECLARE @totalCount NVARCHAR(1000) EXECUTE dbo.PaginationWithOffsetInFirstPage 'rowid,[hotelId],[hotelName]' , -- varchar(500) 'dbo.TB_HotelList' , -- varchar(100) 'hotelId' , -- varchar(100) 'asc' , -- varchar(50) '1=1 and cityId=215' , -- varchar(100) 1, -- int 20, -- int 5, @pageCount OUTPUT , -- int @totalCount OUTPUT SELECT STR(@pageCount) , @totalCount SELECT '语句执行花费时间(毫秒)' = DATEDIFF(ms, @d, GETDATE()) go --调用非首页数据的存储过程 DECLARE @pageCount INT DECLARE @totalCount NVARCHAR(1000) EXECUTE dbo.PaginationWithOffsetNotInFirstPage 'rowid,[hotelId],[hotelName]' , -- varchar(500) 'dbo.TB_HotelList' , -- varchar(100) 'hotelId' , -- varchar(100) 'asc' , -- varchar(50) '1=1 and cityId=215' , -- varchar(100) 3, -- int 20, -- int 5, @pageCount OUTPUT , -- int @totalCount OUTPUT SELECT STR(@pageCount) , @totalCount --不带偏移量的通用 存储过程 CREATE PROC Pagination @columns VARCHAR (500) , --要显示的列名,用逗号隔开 @tableName VARCHAR (100) , --要查询的表名 @orderColumnName VARCHAR (100) , --排序的列名 @ order VARCHAR (50) , --排序的方式,升序为asc,降序为 desc @ where VARCHAR (100) , --where 条件,如果不带查询条件,请用 1=1 @pageIndex INT , --当前页索引 @pageSize INT , --页大小(每页显示的记录条数) @pageCount INT OUTPUT , --总页数,输出参数 @totalCount INT OUTPUT --总记录数,输出参数 AS BEGIN DECLARE @sqlRecordCount NVARCHAR(1000) --得到总记录条数的语句 DECLARE @sqlSelect NVARCHAR(1000) --查询语句 SET @sqlRecordCount = N 'select @recordCount=count(*) from ' + @tableName + ' where ' + @ where DECLARE @recordCount INT --保存总记录条数的变量 EXEC sp_executesql @sqlRecordCount, N '@recordCount int output' , @recordCount OUTPUT --动态 sql 传参 SET @totalCount = @recordCount --把总记录数赋给输出参数 IF ( @recordCount % @pageSize = 0 ) --如果总记录条数可以被页大小整除 SET @pageCount = @recordCount / @pageSize --总页数就等于总记录条数除以页大小 ELSE --如果总记录条数不能被页大小整除 SET @pageCount = @recordCount / @pageSize + 1 --总页数就等于总记录条数除以页大小加1 SET @sqlSelect = N 'select top' + STR(@pageSize) + @columns + ' from ( select row_number() over (order by ' + @orderColumnName + ' ' + @ order + ') as rowId,* from ' + @tableName + ' with(nolock) where ' + @ where + ') as A where A.rowId >' + STR(( @pageindex - 1 ) * @pageSize) --STR(( @pageIndex - 1 )* @pageSize + 1) + ' and ' --+ STR(@pageIndex * @pageSize) EXEC (@sqlSelect) --执行动态Sql END go |
创建时间:2020.09.24 更新时间:
博客园 滔Roy https://www.cnblogs.com/guorongtao 希望内容对你有所帮助,谢谢!
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
· 开发者必知的日志记录最佳实践
· SQL Server 2025 AI相关能力初探
· Linux系列:如何用 C#调用 C方法造成内存泄露
· AI与.NET技术实操系列(二):开始使用ML.NET
· 【自荐】一款简洁、开源的在线白板工具 Drawnix
· 没有Manus邀请码?试试免邀请码的MGX或者开源的OpenManus吧
· 园子的第一款AI主题卫衣上架——"HELLO! HOW CAN I ASSIST YOU TODAY
· 无需6万激活码!GitHub神秘组织3小时极速复刻Manus,手把手教你使用OpenManus搭建本
· C#/.NET/.NET Core优秀项目和框架2025年2月简报