各种 分页存储过程整理
一、TOP n 实现的通用分页存储过程(转自邹建)
CREATE PROC sp_PageView @tbname sysname, --要分页显示的表名 @FieldKey nvarchar(1000), --用于定位记录的主键(惟一键)字段,可以是逗号分隔的多个字段 @PageCurrent int=1, --要显示的页码 @PageSize int=10, --每页的大小(记录数) @FieldShow nvarchar(1000)='', --以逗号分隔的要显示的字段列表,如果不指定,则显示所有字段 @FieldOrder nvarchar(1000)='', --以逗号分隔的排序字段列表,可以指定在字段后面指定DESC/ASC 用于指定排序顺序 @Where nvarchar(1000)='', --查询条件 @PageCount int OUTPUT --总页数 AS SET NOCOUNT ON --检查对象是否有效 IF OBJECT_ID(@tbname) IS NULL BEGINRAISERROR(N'对象"%s"不存在',1,16,@tbname)RETURN END IF OBJECTPROPERTY(OBJECT_ID(@tbname),N'IsTable')=0AND OBJECTPROPERTY(OBJECT_ID(@tbname),N'IsView')=0AND OBJECTPROPERTY(OBJECT_ID(@tbname),N'IsTableFunction')=0 BEGINRAISERROR(N'"%s"不是表、视图或者表值函数',1,16,@tbname)RETURN END--分页字段检查 IF ISNULL(@FieldKey,N'')='' BEGINRAISERROR(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'' ELSESET @FieldOrder=N'ORDER BY '+LTRIM(@FieldOrder) IF ISNULL(@Where,N'')=N''SET @Where=N'' ELSESET @Where=N'WHERE ('+@Where+N')'--如果@PageCount为NULL值,则计算总页数(这样设计可以只在第一次计算总页数,以后调用时,把总页数传回给存储过程,避免再次计算总页数,对于不想计算总页数的处理而言,可以给@PageCount赋值) IF @PageCount IS NULL BEGINDECLARE @sql nvarchar(4000)SET @sql=N'SELECT @PageCount=COUNT(*)'+N' FROM '+@tbname+N' '+@WhereEXEC sp_executesql @sql,N'@PageCount int OUTPUT',@PageCount OUTPUTSET @PageCount=(@PageCount+@PageSize-1)/@PageSize END--计算分页显示的TOPN值 DECLARE @TopN varchar(20),@TopN1 varchar(20) SELECT @TopN=@PageSize,@TopN1=(@PageCurrent-1)*@PageSize--第一页直接显示 IF @PageCurrent=1EXEC(N'SELECT TOP '+@TopN+N' '+@FieldShow+N' FROM '+@tbname+N' '+@Where+N' '+@FieldOrder) ELSE BEGIN--处理别名IF @FieldShow=N'*'SET @FieldShow=N'a.*'--生成主键(惟一键)处理条件DECLARE @Where1 nvarchar(4000),@Where2 nvarchar(4000),@s nvarchar(1000),@Field sysnameSELECT @Where1=N'',@Where2=N'',@s=@FieldKeyWHILE CHARINDEX(N',',@s)>0SELECT @Field=LEFT(@s,CHARINDEX(N',',@s)-1),@s=STUFF(@s,1,CHARINDEX(N',',@s),N''),@Where1=@Where1+N' AND a.'+@Field+N'=b.'+@Field,@Where2=@Where2+N' AND b.'+@Field+N' IS NULL',@Where=REPLACE(@Where,@Field,N'a.'+@Field),@FieldOrder=REPLACE(@FieldOrder,@Field,N'a.'+@Field),@FieldShow=REPLACE(@FieldShow,@Field,N'a.'+@Field)SELECT @Where=REPLACE(@Where,@s,N'a.'+@s),@FieldOrder=REPLACE(@FieldOrder,@s,N'a.'+@s),@FieldShow=REPLACE(@FieldShow,@s,N'a.'+@s),@Where1=STUFF(@Where1+N' AND a.'+@s+N'=b.'+@s,1,5,N''), @Where2=CASEWHEN @Where='' THEN N'WHERE ('ELSE @Where+N' AND ('END+N'b.'+@s+N' IS NULL'+@Where2+N')'--执行查询EXEC(N'SELECT TOP '+@TopN+N' '+@FieldShow+N' FROM '+@tbname+N' a LEFT JOIN(SELECT TOP '+@TopN1+N' '+@FieldKey+N' FROM '+@tbname+N' a '+@Where+N' '+@FieldOrder+N')b ON '+@Where1+N' '+@Where2+N' '+@FieldOrder) END
二、字符串缓存实现的通用分页存储过程(转自邹建)
CREATE PROC sp_PageView @tbname sysname, --要分页显示的表名 @FieldKey sysname, --用于定位记录的主键(惟一键)字段,只能是单个字段 @PageCurrent int=1, --要显示的页码 @PageSize int=10, --每页的大小(记录数) @FieldShow nvarchar(1000)='', --以逗号分隔的要显示的字段列表,如果不指定,则显示所有字段 @FieldOrder nvarchar(1000)='', --以逗号分隔的排序字段列表,可以指定在字段后面指定DESC/ASC 用于指定排序顺序 @Where nvarchar(1000)='', --查询条件 @PageCount int OUTPUT --总页数 AS DECLARE @sql nvarchar(4000) SET NOCOUNT ON --检查对象是否有效 IF OBJECT_ID(@tbname) IS NULL BEGINRAISERROR(N'对象"%s"不存在',1,16,@tbname)RETURN END IF OBJECTPROPERTY(OBJECT_ID(@tbname),N'IsTable')=0AND OBJECTPROPERTY(OBJECT_ID(@tbname),N'IsView')=0AND OBJECTPROPERTY(OBJECT_ID(@tbname),N'IsTableFunction')=0 BEGINRAISERROR(N'"%s"不是表、视图或者表值函数',1,16,@tbname)RETURN END--分页字段检查 IF ISNULL(@FieldKey,N'')='' BEGINRAISERROR(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'' ELSESET @FieldOrder=N'ORDER BY '+LTRIM(@FieldOrder) IF ISNULL(@Where,N'')=N''SET @Where=N'' ELSESET @Where=N'WHERE ('+@Where+N')'--如果@PageCount为NULL值,则计算总页数(这样设计可以只在第一次计算总页数,以后调用时,把总页数传回给存储过程,避免再次计算总页数,对于不想计算总页数的处理而言,可以给@PageCount赋值) IF @PageCount IS NULL BEGINSET @sql=N'SELECT @PageCount=COUNT(*)'+N' FROM '+@tbname+N' '+@WhereEXEC sp_executesql @sql,N'@PageCount int OUTPUT',@PageCount OUTPUTSET @PageCount=(@PageCount+@PageSize-1)/@PageSize END--计算分页显示的TOPN值 DECLARE @TopN varchar(20),@TopN1 varchar(20) SELECT @TopN=@PageSize,@TopN1=@PageCurrent*@PageSize --第一页直接显示 IF @PageCurrent=1EXEC(N'SELECT TOP '+@TopN+N' '+@FieldShow+N' FROM '+@tbname+N' '+@Where+N' '+@FieldOrder) ELSE BEGINSELECT @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' '+@FieldOrderSET ROWCOUNT @PageCurrentEXEC sp_executesql @sql,N'@n int,@s nvarchar(4000) OUTPUT',@PageCurrent,@sql OUTPUTSET ROWCOUNT 0IF @sql=N''EXEC(N'SELECT TOP 0'+N' '+@FieldShow+N' FROM '+@tbname)ELSEBEGINSET @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
三、使用系统存储过程实现的通用分页存储过程(转自邹建)
CREATE PROC sp_PageView @sql ntext, --要执行的sql语句 @PageCurrent int=1, --要显示的页码 @PageSize int=10, --每页的大小 @PageCount int OUTPUT --总页数 AS SET NOCOUNT ON DECLARE @p1 int --初始化分页游标 EXEC sp_cursoropen@cursor=@p1 OUTPUT,@stmt=@sql,@scrollopt=1,@ccopt=1,@rowcount=@PageCount OUTPUT--计算总页数 IF ISNULL(@PageSize,0)<1SET @PageSize=10 SET @PageCount=(@PageCount+@PageSize-1)/@PageSize IF ISNULL(@PageCurrent,0)<1 OR ISNULL(@PageCurrent,0)>@PageCountSET @PageCurrent=1 ELSESET @PageCurrent=(@PageCurrent-1)*@PageSize+1--显示指定页的数据 EXEC sp_cursorfetch @p1,16,@PageCurrent,@PageSize--关闭分页游标 EXEC sp_cursorclose @p1
四、SQL 2005的ROW_NUMBER()实现分页功能
DECLARE @pagenum AS INT, @pagesize AS INT SET @pagenum = 2 SET @pagesize = 3 SELECT * FROM (SELECT ROW_NUMBER() OVER(ORDER BY newsid DESC) AS rownum,newsid, topic, ntime, hitsFROM news) AS D WHERE rownum BETWEEN (@pagenum-1)*@pagesize+1 AND @pagenum*@pagesize ORDER BY newsid DESC
五、使用内存表
create proc Proc_paged (@pagesize int,@pagenum int,@pagecount int output ) as begin --声明变量 declare @tmptable table(id int identity (1,1),userid nchar(5)) declare @idBengin int declare @idend int --构造内存表 insert into @tmptable (userid )(select userid from users) select @pagecount=count(*) from @tmptable if(@pagecount%@pagesize>0) set @pagecount=@pagecount/@pagesize+1 else set @pagecount=@pagecount/@pagesize set @idBengin=(@pagenum-1)*@pagesize set @idend=@idBengin+@pagesize select t2.id,t1.* from users t1,@tmptable t2 where t1.userid=t2.userid andt2.id>@idBengin and t2.id<=@idend end
六、SQL 2005 版本 通用分页存储过程
Create PROCEDURE [dbo].[Pagination] @Page int = 1, -- 当前页码 @PageSize int = 10, -- 每页记录条数(页面大小) @Table nvarchar(500), -- 表名或视图名,甚至可以是嵌套SQL:(Select * From Tab Where ID>1000) Tab @Field nvarchar(200) = '*', -- 返回记录集字段名,","隔开,默认是"*" @OrderBy nvarchar(100) = 'ID ASC', -- 排序规则 @Filter nvarchar(500), -- 过滤条件 @MaxPage smallint output, -- 执行结果 -1 error, 0 false, maxpage true @TotalRow int output, -- 记录总数 /* 2007-07-12 22:11:00 update */ @Descript varchar(100) output -- 结果描述 AS BEGIN Set ROWCOUNT @PageSize;Set @Descript = 'successful'; -------------------参数检测---------------- IF LEN(RTRIM(LTRIM(@Table))) !> 0 BeginSet @MaxPage = 0;Set @Descript = 'table name is empty';Return; EndIF LEN(RTRIM(LTRIM(@OrderBy))) !> 0 BeginSet @MaxPage = 0;Set @Descript = 'order is empty';Return; EndIF ISNULL(@PageSize,0) <= 0 BeginSet @MaxPage = 0;Set @Descript = 'page size error';Return; EndIF ISNULL(@Page,0) <= 0 BeginSet @MaxPage = 0;Set @Descript = 'page error';Return; End -------------------检测结束----------------Begin Try-- 整合SQLDeclare @SQL nvarchar(4000), @Portion nvarchar(4000);Set @Portion = ' ROW_NUMBER() OVER (ORDER BY ' + @OrderBy + ') AS ROWNUM FROM ' + @Table;Set @Portion = @Portion + (CASE WHEN LEN(@Filter) >= 1 THEN (' Where ' + @Filter + ') AS tab') ELSE (') AS tab') END);Set @SQL = 'Select TOP(' + CAST(@PageSize AS nvarchar(8)) + ') ' + @Field + ' FROM (Select ' + @Field + ',' + @Portion;Set @SQL = @SQL + ' Where tab.ROWNUM > ' + CAST((@Page-1)*@PageSize AS nvarchar(8));-- 执行SQL, 取当前页记录集Execute(@SQL);---------------------------------------------------------------------- 整合SQLSet @SQL = 'Set @Rows = (Select MAX(ROWNUM) FROM (Select' + @Portion + ')';-- 执行SQL, 取最大页码Execute sp_executesql @SQL, N'@Rows int output', @TotalRow output;Set @MaxPage = (CASE WHEN (@TotalRow % @PageSize)<>0 THEN (@TotalRow / @PageSize + 1) ELSE (@TotalRow / @PageSize) END); End Try Begin Catch-- 捕捉错误Set @MaxPage = -1;Set @Descript = 'error line: ' + CAST(ERROR_LINE() AS varchar(8)) + ', error number: ' + CAST(ERROR_NUMBER() AS varchar(8)) + ', error message: ' + ERROR_MESSAGE();Return; End Catch;-- 执行成功 Return; END
整理自:http://www.cnblogs.com/onlytiancai/archive/2009/03/26/1421956.html
转载于:https://www.cnblogs.com/xufeiyang/articles/3245033.html
各种 分页存储过程整理相关推荐
- 高性能SQLServer通用分页存储过程
这是我之前整理的高性能SQLServer 通用分页存储过程,测试性能还不错,特此分享出来,如果有人能更好地优化,请留言,谢谢! SQL代码 1 USE [数据库名称] 2 GO 3 /***** ...
- 数据库:SQLServer分页查询整理
作为程序员来说,与数据库打交道是十分频繁的分页查询是一个开发者必须掌握的基本知识点,目前整理了下面三种SQLServer分页查询语句的写法,仅供参考. 一.Top Not IN 方式(查询靠前的数据较 ...
- [百万级]通用存储过程.分页存储过程
/* 名称:spAll_ReturnRows 输入: 输出: 调用: EXEC spAll_ReturnRows 'SELECT * FROM 表名', 页号, 返回记录数, '主键', ...
- 动软 mysql 分页_动软.NET 分页存储过程UP_GetRecordByPage
1, ------------------------------------ --用途:支持任意排序的分页存储过程 --说明: ----------------------------------- ...
- 通用分页存储过程(转自邹建)
--TOP n 实现的通用分页存储过程(转自邹建) CREATE PROC sp_PageView @tbname sysname, --要分页显示的表名 @Fie ...
- oracle存储过程 多条件,Oracle多条件查询实际分页存储过程实操
以下的文章主要是介绍Oracle多条件查询分页存储过程,以下就是Oracle多条件查询分页存储过程具体方案的描述,希望在你今后的学习中会有所帮助.将业务逻辑放到Oracle中使得后台代码很精简,Ora ...
- ASP.NET分页存储过程自定义用户控件
网上有很多分页存储过程,但是基本上都是提供一个单纯的存储过程,没有具体的怎样去实现.最近做一个项目用户的数数据相当大(一百万以上的数据),如果用.NET自带的分页基本上是跑不动了,不是提示超时就是死在 ...
- 完整SQL分页存储过程(支持多表联接)
Code /********************************************************* * 作 用:数据分页(完整SQL分页存储过程(支持多表联接)) ...
- sqlserver2000分页存储过程(原创)
刚刚用了博客园,感觉这里的气氛真的很好,发布这几天写的一个分页存储过程,请dudu多多关照,请各位大牛指正. 功能:海量优化,支持任何字段排序,可支持随机取数据,导出所有数据功能,用了id(整型)比较 ...
最新文章
- 设计模式学习笔记-中介模式
- baidu mp3竟然还加密,太扯了
- 一旦一个业务可以由一个人来全部完成而不涉及分工,就会产生单干的情况
- NYOJ 275 队花的烦恼一
- OpenWrt配置篇
- python调用 matlab库_python调用matlab的搜索结果-阿里云开发者社区
- python怎么返回上一行代码_Python实现判断一行代码是否为注释的方法
- 口腔取模过程及注意事项_为什么牙齿矫正前要拍片取模,没有拍片取模就设计不了详细方案!...
- SoapUI中文乱码
- con 元器件符号_altium designer常用元件电气符号和封装形式
- IOS捷径早安,创建自动化可实现自动化叫醒
- 光凭求职技巧如何可以突围?
- 乐高创意机器人moc_深度乐高 篇一:大神带你玩转乐高 Speed 系列套内 MOC
- Redis源码解读(二十五)——集群模式—failover
- 知识图谱发展的难点 构建行业知识图谱的重要性
- 合服 两个服务器都有什么作用,阴阳师合服是什么意思?合服合区问题汇总详解[多图]...
- u盘插在电脑上灯亮没有反应_u盘插电脑灯在闪但是没反应怎么办
- Mplayer完美安装手册(转)
- 使用FreeType实现矢量字体的粗体、斜体、描边、阴影效果
- android ota权限,Android手机Root后不能接收OTA?
热门文章
- HANDLE:句柄的概念
- linux 扩展zhu分区,Linux分区调整(LVM和非LVM环境中扩容和缩小)
- 服务器虚拟机密度,服务器整合:虚拟机密度大未必好事
- linux系统中使用chattr命令的,chattr命令怎么用
- 048_Calendar日历
- 033_webpack打包ES6模块化工程
- 017_SpringBoot异常处理方式-自定义错误页面
- 006_Ajax发送POST请求
- 多元二次方程 python_Python 二次方程
- mysql show full processlist;_mysql show full processlist 详解