1.兼容2000
2.支持多字段排序,比如 A.DESC,B.DESC最重要一点,性能一定要高。 最后麻烦大家能够提供实用点的,别Google一气贴过来。麻烦大家了。

解决方案 »

  1.   

    推荐使用我的分页:
    http://www.dmblogs.com/nzBlog/article.asp?id=25
      

  2.   

    SET   QUOTED_IDENTIFIER   ON     
      GO   
      SET   ANSI_NULLS   ON     
      GO   
        
      /*--用存储过程实现的分页程序   
        
        显示指定表、视图、查询结果的第X页   
        对于表中主键或标识列的情况,直接从原表取数查询,其它情况使用临时表的方法   
        如果视图或查询结果中有主键,不推荐此方法   
        
      --邹建   2003.09(引用请保留此信息)--*/   
        
      /*--调用示例   
        exec   p_show   '地区资料'   
        
        exec   p_show   '地区资料',5,3,'地区编号,地区名称,助记码','地区编号'   
      --*/   
      ALTER     Proc   UP_Show   
      @QueryStr   nvarchar(4000),   --表名、视图名、查询语句   
      @PageSize   int=10,       --每页的大小(行数)   
      @PageCurrent   int=1,       --要显示的页   
      @FdShow   nvarchar   (4000)='',   --要显示的字段列表,如果查询结果有标识字段,需要指定此值,且不包含标识字段   
      @FdOrder   nvarchar   (1000)='',   --排序字段列表   
      @Rows   int   =   null   OUTPUT             --   输出记录数,   如果@rows为null,   则输出记录数,   否则不要输出   
      as   
      set   nocount   on   
      declare   @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)   
        return   
      end   
        
      --如果是表,则检查表中是否有标识更或主键   
      if   @Obj_ID   is   not   null   and   objectproperty(@Obj_ID,'IsTable')=1   
      begin   
        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')   
            goto   lbusetemp     --如果表中无主键,则用临时表处理   
        
          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)   
            goto   lbusepk   
          end   
        end   
      end   
      else   
        goto   lbusetemp   
        
      /*--使用标识列或主键为单一字段的处理方法--*/   
      lbuseidentity:     
      if   @Rows   is   null   
      begin   
      declare   @lbuseidentity   nvarchar(1000)   
      set   @lbuseidentity   =   'select   @rows   =   count(*)   from   '+@QueryStr   
      exec   sp_executesql   @lbuseidentity,   N'@Rows   int   out',   @Rows   out   
      end   
        exec('select   top   '+@Id1+@FdShow+'   from   '+@QueryStr   
          +'   where   '+@FdName+'   not   in(select   top   '   
          +@Id2+'   '+@FdName+'   from   '+@QueryStr+@FdOrder   
          +')'+@FdOrder   
          )   
        return   
        
      /*--表中有复合主键的处理方法--*/   
      lbusepk:       
      if   @Rows   is   null   
      begin   
      declare   @lbusepk   nvarchar(1000)   
      set   @lbusepk   =   'select   @rows   =   count(*)   from   '+@QueryStr   
      exec   sp_executesql   @lbusepk,   N'@Rows   int   out',   @Rows   out   
      end   
        
        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'   
          )   
        return   
        
      /*--用临时表处理的方法--*/   
      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))   
        
      declare   @lbusetemp   nvarchar(4000)   
      set   @lbusetemp   =   'select   '+@FdName+'=identity(int,0,1),'+@FdShow+'   
          into   #tb   from'+@QueryStr+@FdOrder   
      +case   when   @Rows   is   null   then   '   set   @Rows   =   @@rowcount   '   else   ''   end   +   '   
        select   '+@FdShow+'   from   #tb   where   '+@FdName+'   between   '   
        +@Id1+'   and   '+@Id2   
        exec   sp_executesql   @lbusetemp,     N'@Rows   int   out',   @Rows   out   
      GO   
      SET   QUOTED_IDENTIFIER   OFF     
      GO   
      SET   ANSI_NULLS   ON     
      GO   
        
      

  3.   

    用Set RowcountDeclare @ID int
    Declare @MoveRecords int--@CurrentPage和@PageSize是传入参数
    Set @MoveRecords=@CurrentPage * @PageSize+1--下面两行实现快速滚动到我们要取的数据的行,并把ID记录下来
    Set Rowcount @MoveRecords
    Select @ID=ID from Table1 Order by IDSet Rowcount @PageSize
    --最恨为了减少麻烦使用*了,但是在这里为了说明方便,暂时用一下
    Select * From Table1 Where ID>=@ID Order By ID
    Set Rowcount 0
      

  4.   

    感谢各位的支持,关注ing
    期待能够有不错的收获,我会一个一个测试下的。