设为首页 收藏本站
查看: 643|回复: 0

[经验分享] 邹建的 sql server 分页存储过程 以备用

[复制链接]

尚未签到

发表于 2016-11-6 01:54:53 | 显示全部楼层 |阅读模式

  • IFOBJECT_ID(N'dbo.pagination')ISNOTNULL
  • DROPPROCEDUREdbo.pagination
  • GO

  • /**//*--实现分页的通用存储过程

  • 显示指定表、视图、查询结果的第X页
  • 对于表中主键或标识列的情况,直接从原表取数查询,其它情况使用临时表的方法
  • 如果视图或查询结果中有主键,不推荐此方法
  • 如果使用查询语句,而且查询语句使用了orderby,则查询语句必须包含top语句

  • 最后更新时间:2008.01.20
  • --邹建2003.09(引用请保留此信息)--*/

  • /**//*--调用示例
  • EXECdbo.pagination
  • @QueryStr=N'tb',
  • @PageSize=5,
  • @PageCurrent=3,
  • @FdShow='id,colid,name',
  • @FdOrder='colid,name'
  • selectid,colidfromtb
  • orderbycolid,name


  • EXECdbo.pagination
  • @QueryStr=N'
  • SELECTTOP100PERCENT
  • *
  • FROMdbo.sysobjects
  • ORDERBYxtype',
  • @PageSize=5,
  • @PageCurrent=2,
  • @FdShow='name,xtype',
  • @FdOrder='xtype,name'
  • --*/
  • CREATEPROCdbo.pagination
  • @QueryStrnvarchar(4000),--表名、视图名、查询语句
  • @PageSizeint=10,--每页的大小(行数)
  • @PageCurrentint=1,--要显示的页
  • @FdShownvarchar(4000)=N'',--要显示的字段列表,如果查询结果不需要标识字段,需要指定此值,且不包含标识字段
  • @FdOrdernvarchar(1000)=N''--排序字段列表
  • AS
  • SETNOCOUNTON
  • DECLARE
  • @FdNamesysname,--表中的主键或表、临时表中的标识列名
  • @Id1sysname,--开始和结束的记录号
  • @Id2sysname,
  • @Obj_IDint--对象ID

  • --表中有复合主键的处理
  • DECLARE
  • @strfdnvarchar(2000),--复合主键列表
  • @strjoinnvarchar(4000),--连接字段
  • @strwherenvarchar(2000)--查询条件


  • SELECT
  • @Obj_ID=OBJECT_ID(@QueryStr),
  • @FdShow=CASE
  • WHEN@FdShow>N''THENN''+@FdShow
  • ELSEN'*'
  • END,
  • @FdOrder=CASE
  • WHEN@FdOrder>N''THENN'ORDERBY'+@FdOrder
  • ELSEN''
  • END,
  • @QueryStr=CASE
  • WHEN@Obj_IDISNULLTHENN'('+@QueryStr+N')A'
  • ELSEN''+@QueryStr
  • END

  • --如果显示第一页,可以直接用top来完成
  • IF@PageCurrent=1
  • BEGIN
  • SELECT
  • @Id1=CAST(@PageSizeasvarchar(20))
  • EXEC(N'
  • SELECTTOP'+@Id1+N'
  • '+@FdShow+N'
  • FROM'+@QueryStr+N'
  • '+@FdOrder
  • )
  • RETURN
  • END

  • --如果是表,则检查表中是否有标识更或主键
  • IF@Obj_IDISNULLOROBJECTPROPERTY(@Obj_ID,'IsTable')=0
  • GOTOlb_usetemp
  • ELSE
  • BEGIN
  • SELECT
  • @Id1=CAST(@PageSizeasvarchar(20)),
  • @Id2=CAST((@PageCurrent-1)*@PageSizeasvarchar(20))

  • --标识列
  • SELECT
  • @FdName=name
  • FROMdbo.syscolumns
  • WHEREid=@Obj_ID
  • ANDstatus=0x80
  • IF@@ROWCOUNT=0--如果表中无标识列,则检查表中是否有主键
  • BEGIN
  • DECLARE
  • @pk_numberint

  • SELECT
  • @strfd=N'',
  • @strjoin=N'',
  • @strwhere=N''

  • SELECT
  • @strfd=@strfd
  • +N','+QUOTENAME(name),
  • @strjoin=@strjoin
  • +N'ANDA.'+QUOTENAME(name)
  • +N'=B.'+QUOTENAME(name),
  • @strwhere=@strwhere
  • +N'ANDB.'+QUOTENAME(name)+N'ISNULL'
  • FROM(
  • SELECT
  • IX.id,IX.indid,
  • IXC.colid,ixc.keyno,
  • C.name
  • FROMdbo.sysobjectsO,
  • dbo.sysindexesIX,
  • dbo.sysindexkeysIXC,
  • dbo.syscolumnsC
  • WHEREO.parent_obj=@Obj_ID
  • ANDO.xtype='PK'
  • ANDO.name=IX.name
  • ANDIX.id=@Obj_ID
  • ANDIX.id=IXC.id
  • ANDIX.indid=IXC.indid
  • ANDIXC.id=C.id
  • ANDIXC.colid=C.colid
  • )A
  • ORDERBYkeyno

  • SELECT
  • @pk_number=@@ROWCOUNT,
  • @strfd=STUFF(@strfd,1,1,N''),
  • @strjoin=STUFF(@strjoin,1,5,N''),
  • @strwhere=STUFF(@strwhere,1,5,N'')

  • IF@pk_number=0
  • GOTOlb_usetemp--如果表中无主键,则用临时表处理
  • ELSEIF@pk_number=1
  • BEGIN
  • SELECT
  • @FdName=@strfd
  • GOTOlb_useidentity--使用单一主键
  • END
  • ELSE
  • GOTOlb_usepk--使用复合主键
  • END
  • END

  • /**//*--使用标识列或主键为单一字段的处理方法--*/
  • lb_useidentity:
  • EXEC(N'
  • SELECTTOP'+@Id1+N'
  • '+@FdShow+N'
  • FROM'+@QueryStr+N'
  • WHERE'+@FdName+'NOTIN(
  • SELECTTOP'+@Id2+N'
  • '+@FdName+'
  • FROM'+@QueryStr+N'
  • '+@FdOrder+N')
  • '+@FdOrder+N'
  • ')
  • RETURN

  • /**//*--表中有复合主键的处理方法--*/
  • lb_usepk:
  • EXEC(N'
  • SELECT
  • '+@FdShow+N'
  • FROM(
  • SELECTTOP'+@Id1+N'
  • A.*
  • FROM'+@QueryStr+N'A
  • LEFTJOIN(
  • SELECTTOP'+@Id2+N'
  • '+@strfd+N'
  • FROM'+@QueryStr+N'
  • '+@FdOrder+N'
  • )B
  • ON'+@strjoin+N'
  • WHERE'+@strwhere+N'
  • '+@FdOrder+N'
  • )A
  • '+@FdOrder+N'
  • ')
  • RETURN

  • /**//*--用临时表处理的方法--*/
  • lb_usetemp:
  • SELECT
  • @FdName=QUOTENAME(N'ID_'+CAST(NEWID()asvarchar(40))),
  • @Id1=CAST(@PageSize*(@PageCurrent-1)asvarchar(20)),
  • @Id2=CAST(@PageSize*@PageCurrent-1asvarchar(20))

  • EXEC(N'
  • SELECT
  • '+@FdName+N'=IDENTITY(int,0,1),
  • '+@FdShow+N'
  • INTO#tb
  • FROM(
  • SELECTTOP100PERCENT
  • *
  • FROM'+@QueryStr+N'
  • '+@FdOrder+N'
  • )A
  • '+@FdOrder+N'

  • SELECT
  • '+@FdShow+N'
  • FROM#tb
  • WHERE'+@FdName+'BETWEEN'+@Id1+'AND'+@Id2+N'
  • '
  • )
  • GO

运维网声明 1、欢迎大家加入本站运维交流群:群②:261659950 群⑤:202807635 群⑦870801961 群⑧679858003
2、本站所有主题由该帖子作者发表,该帖子作者与运维网享有帖子相关版权
3、所有作品的著作权均归原作者享有,请您和我们一样尊重他人的著作权等合法权益。如果您对作品感到满意,请购买正版
4、禁止制作、复制、发布和传播具有反动、淫秽、色情、暴力、凶杀等内容的信息,一经发现立即删除。若您因此触犯法律,一切后果自负,我们对此不承担任何责任
5、所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其内容的准确性、可靠性、正当性、安全性、合法性等负责,亦不承担任何法律责任
6、所有作品仅供您个人学习、研究或欣赏,不得用于商业或者其他用途,否则,一切后果均由您自己承担,我们对此不承担任何法律责任
7、如涉及侵犯版权等问题,请您及时通知我们,我们将立即采取措施予以解决
8、联系人Email:admin@iyunv.com 网址:www.yunweiku.com

所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其承担任何法律责任,如涉及侵犯版权等问题,请您及时通知我们,我们将立即处理,联系人Email:kefu@iyunv.com,QQ:1061981298 本贴地址:https://www.yunweiku.com/thread-296147-1-1.html 上篇帖子: sql server 2005 內建的分頁機制 下篇帖子: SQL Server中获取第一天、最后一天
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

扫码加入运维网微信交流群X

扫码加入运维网微信交流群

扫描二维码加入运维网微信交流群,最新一手资源尽在官方微信交流群!快快加入我们吧...

扫描微信二维码查看详情

客服E-mail:kefu@iyunv.com 客服QQ:1061981298


QQ群⑦:运维网交流群⑦ QQ群⑧:运维网交流群⑧ k8s群:运维网kubernetes交流群


提醒:禁止发布任何违反国家法律、法规的言论与图片等内容;本站内容均来自个人观点与网络等信息,非本站认同之观点.


本站大部分资源是网友从网上搜集分享而来,其版权均归原作者及其网站所有,我们尊重他人的合法权益,如有内容侵犯您的合法权益,请及时与我们联系进行核实删除!



合作伙伴: 青云cloud

快速回复 返回顶部 返回列表