通用分页存储过程

来源:互联网 发布:导入题库答题软件 编辑:程序博客网 时间:2024/06/05 16:19
/****** Object:  StoredProcedure [dbo].[up_PageSplit]    Script Date: 03/18/2013 17:19:57 ******/ /*--实现分页的通用存储过程    显示指定表、视图、查询结果的第X页    对于表中主键或标识列的情况,直接从原表取数查询,其它情况使用临时表的方法    如果视图或查询结果中有主键,不推荐此方法    如果使用查询语句,而且查询语句使用了order by,则查询语句必须包含top 语句--邹建 2003.09(引用请保留此信息)--*//*--调用示例    exec p_show '地区资料'    exec p_show 'select top 100 percent * from 地区资料 order by 地区名称',5,3,'地区编号,地区名称,助记码'--*//*  修改 1、为了提高关联表查询效率,增加一个参数@CoreTable.仍兼容原来的用法。  如果原过程已有调用,可以把该参数放在最后,则不用改动原来的调用代码。  关于应用@CoreTable时的要求,请参见参数后的说明。 如果执行发生问题,  请检查输出的sql语句。  --- ybs 2007.6.28 2、增加了@DoCount参数,当此参数值为1时,以第二个结果集的形式返回总记录数。               --- ybs 2007.6.28*/if exists (select * from dbo.sysobjects where id = object_id(N'[dbo].[up_PageSplit] ') and OBJECTPROPERTY(id, N'IsProcedure') = 1)drop procedure [dbo].[p_show]GOcreate Proc [dbo].[up_PageSplit]@QueryStr nvarchar(4000),    --表名、视图名、查询语句@CoreTable nvarchar(50)='',     --核心表(查询结果中的记录与该表中的记录一一对应)                                --为提高效率,CoreTable最好使用自增长ID,                                --要求CoreTable主键列必须在@QueryStr中存在,且不能重命名@PageSize int=10,              --每页的大小(行数)@PageCurrent int=1,            --要显示的页@FdShow nvarchar (4000)='',    --要显示的字段列表,如果查询结果不需要标识字段,需要指定此值,且不包含标识字段@FdOrder nvarchar (1000)='',   --排序字段列表@DoCount bit = 0              --为0表示不统计总记录数,如果为1,则在第二个结果集中返回总记录数asset nocount ondeclare @FdName nvarchar(250)    --表中的主键或表、临时表中的标识列名    ,@Id1 varchar(20),@Id2 varchar(20)    --开始和结束的记录号    ,@Obj_ID int                --对象ID--表中有复合主键的处理declare @strfd nvarchar(2000)    --复合主键列表    ,@strjoin nvarchar(4000)    --连接字段    ,@strwhere nvarchar(2000)    --查询条件select @Obj_ID=object_id(@QueryStr)    ,@FdShow=case isnull(@FdShow,'') when '' then ' *' else ' '+@FdShow end    ,@FdOrder=case isnull(@FdOrder,'') when '' then '' else ' order by '+@FdOrder end    ,@QueryStr=case when @Obj_ID is not null then ' '+@QueryStr else ' ('+@QueryStr+') a' end--如果显示第一页,可以直接用top来完成if @PageCurrent=1    begin    select @Id1=cast(@PageSize as varchar(20))    exec('select top '+@Id1+@FdShow+' from '+@QueryStr+@FdOrder) if(@DoCount = 1)    exec( 'select count(*) as RecourdCount from '+ @QueryStr )    returnend--核心表相关if(@Obj_ID is null and @CoreTable <> '')begin    set @Obj_ID=object_id(@CoreTable)end--如果是表,则检查表中是否有标识更或主键if @Obj_ID is not null and objectproperty(@Obj_ID,'IsTable')=1begin    select @Id1=cast(@PageSize as varchar(20))        ,@Id2=cast((@PageCurrent-1)*@PageSize as varchar(20))    select @FdName=name from syscolumns where id=@Obj_ID and status=0x80    if @@rowcount=0            --如果表中无标识列,则检查表中是否有主键    begin        if not exists(select 1 from sysobjects where parent_obj=@Obj_ID and xtype='PK')        begin           --goto lbusetemp        --如果表中无主键,则用临时表处理           /*--用临时表处理的方法--*/    select @FdName='[ID_'+cast(newid() as varchar(40))+']'     ,@Id1=cast(@PageSize*(@PageCurrent-1) as varchar(20))     ,@Id2=cast(@PageSize*@PageCurrent-1 as varchar(20))     exec('select '+@FdName+'=identity(int,0,1),'+@FdShow+'         into #tb from'+@QueryStr+@FdOrder+'     select '+@FdShow+' from #tb where '+@FdName+' between '     +@Id1+' and '+@Id2     )     --print ('select '+@FdName+'=identity(int,0,1),'+@FdShow+'    --     into #tb from'+@QueryStr+@FdOrder+'    -- select '+@FdShow+' from #tb where '+@FdName+' between '    -- +@Id1+' and '+@Id2    -- )    if(@DoCount = 1)       exec( 'select count(*) as RecourdCount from '+ @QueryStr )    --print 'use temp table'        end        select @FdName=name from syscolumns where id=@Obj_ID and colid in(            select colid from sysindexkeys where @Obj_ID=id and indid in(                select indid from sysindexes where @Obj_ID=id and name in(                    select name from sysobjects where xtype='PK' and parent_obj=@Obj_ID            )))        if @@rowcount>1        --检查表中的主键是否为复合主键        begin            select @strfd='',@strjoin='',@strwhere=''            select @strfd=@strfd+',['+name+']'                ,@strjoin=@strjoin+' and a.['+name+']=b.['+name+']'                ,@strwhere=@strwhere+' and b.['+name+'] is null'                from syscolumns where id=@Obj_ID and colid in(                select colid from sysindexkeys where @Obj_ID=id and indid in(                    select indid from sysindexes where @Obj_ID=id and name in(                        select name from sysobjects where xtype='PK' and parent_obj=@Obj_ID                )))            select @strfd=substring(@strfd,2,2000)                ,@strjoin=substring(@strjoin,5,4000)                ,@strwhere=substring(@strwhere,5,4000)            begin             /*--表中有复合主键的处理方法--*/             --goto lbusepk     exec('select '+@FdShow+' from(select top '+@Id1+' a.* from          (select top 100 percent * from '+@QueryStr+@FdOrder+') a          left join (select top '+@Id2+''+@strfd+'          from '+@QueryStr+@FdOrder+') b on '+@strjoin+'          where '+@strwhere+') a'          )     --print ('select '+@FdShow+' from(select top '+@Id1+' a.* from     --     (select top 100 percent * from '+@QueryStr+@FdOrder+') a     --     left join (select top '+@Id2+''+@strfd+'     --     from '+@QueryStr+@FdOrder+') b on '+@strjoin+'     --     where '+@strwhere+') a'     --     )     --  print 'use pk'     if(@DoCount = 1)        exec( 'select count(*) as RecourdCount from '+ @QueryStr )     return            end        end    endendelse begin   --goto lbusetemp   /*--如果是视图,用临时表处理的方法--*/   select @FdName='[ID_'+cast(newid() as varchar(40))+']'    ,@Id1=cast(@PageSize*(@PageCurrent-1) as varchar(20))    ,@Id2=cast(@PageSize*@PageCurrent-1 as varchar(20))   exec('select '+@FdName+'=identity(int,0,1),'+@FdShow+'        into #tb from'+@QueryStr+@FdOrder+'    select '+@FdShow+' from #tb where '+@FdName+' between '    +@Id1+' and '+@Id2    )   --print ('select '+@FdName+'=identity(int,0,1),'+@FdShow+'   --     into #tb from'+@QueryStr+@FdOrder+'   -- select '+@FdShow+' from #tb where '+@FdName+' between '   -- +@Id1+' and '+@Id2   -- )   if(@DoCount = 1)      exec( 'select count(*) as RecourdCount from '+ @QueryStr )   --print 'use temp table'   returnend   /*--如果是表,使用标识列或主键为单一字段的处理方法--*/   /*lbuseidentity*/        exec('select top '+@Id1+@FdShow+' from '+@QueryStr        +' where '+@FdName+' not in(select top '        +@Id2+''+@FdName+' from '+@QueryStr+@FdOrder        +')'+@FdOrder        )   --print 'select top '+@Id1+@FdShow+' from '+@QueryStr   --     +' where '+@FdName+' not in(select top '   --     +@Id2+''+@FdName+' from '+@QueryStr+@FdOrder   --     +')'+@FdOrder   --print 'use identity'   if(@DoCount = 1)      exec( 'select count(*) as RecourdCount from '+ @QueryStr )   return/***********************分页过程 over***************************/GO

原创粉丝点击