请问在sql 中怎么写一个表的分页存储过程 
在.net代码中又该如何调用呢?

解决方案 »

  1.   

    /*--用存储过程实现的分页程序
     显示指定表、视图、查询结果的第X页
     对于表中主键或标识列的情况,直接从原表取数查询,其它情况使用临时表的方法
     如果视图或查询结果中有主键,不推荐此方法--邹建 2003.09(引用请保留此信息)--*//*--调用示例
     exec p_show '地区资料' exec p_show '地区资料',5,3,'地区编号,地区名称,助记码','地区编号'
    --*/if exists (select * from dbo.sysobjects where id = object_id(N'[dbo].[p_show]') 
    and OBJECTPROPERTY(id, N'IsProcedure') = 1)
    drop procedure [dbo].[p_show]
    GOCREATE Proc p_show
    @QueryStr nvarchar(4000), --表名、视图名、查询语句
    @PageSize int=10,   --每页的大小(行数)
    @PageCurrent int=1,   --要显示的页
    @FdShow nvarchar (4000)='',--要显示的字段列表,如果查询结果有标识字段,需要指定此值,且不包含标识字段
    @FdOrder nvarchar (1000)='' --排序字段列表
    as
    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: 
     exec('select top '+@Id1+@FdShow+' from '+@QueryStr
      +' where '+@FdName+' not in(select top '
      +@Id2+' '+@FdName+' from '+@QueryStr+@FdOrder
      +')'+@FdOrder
      )
     return/*--表中有复合主键的处理方法--*/
    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'
      )
     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))exec('select '+@FdName+'=identity(int,0,1),'+@FdShow+'
      into #tb from'+@QueryStr+@FdOrder+'
     select '+@FdShow+' from #tb where '+@FdName+' between '
     +@Id1+' and '+@Id2
     )
    GO本文来自CSDN博客,转载请标明出处:http://blog.csdn.net/fredrickhu/archive/2009/09/18/4566261.aspx
      

  2.   

    CREATE PROCEDURE Pagination  
     
    @tblName   varchar(255),       -- 表名  
     
    @strGetFields varchar(1000) = '*',  -- 需要返回的列  
     
    @fldName varchar(255)='',      -- 排序的字段名  
     
    @PageSize   int = 10,          -- 页尺寸  
     
    @PageIndex  int = 1,           -- 页码  
     
    @doCount  bit = 0,   -- 返回记录总数, 非 0 值则返回  
     
    @OrderType bit = 0,  -- 设置排序类型, 非 0 值则降序  
     
    @strWhere  varchar(1500) = ''  -- 查询条件 (注意: 不要加 where)  
     
    AS  
     
    declare @strSQL   varchar(5000)       -- 主语句  
     
    declare @strTmp   varchar(110)        -- 临时变量  
     
    declare @strOrder varchar(400)        -- 排序类型  
     
     
     
    if @doCount != 0  
     
     begin  
     
       if @strWhere !=''  
     
       set @strSQL = 'select count(*) as Total from ['+ @tblName +'] where '+ @strWhere  
     
       else  
     
       set @strSQL = 'select count(*) as Total from ['+ @tblName +']' 
     
    end  
     
    --以上代码的意思是如果@doCount传递过来的不是0,就执行总数统计。以下的所有代码都 
    --是@doCount为0的情况  
     
    else  
     
    begin  
     
     
     
    if @OrderType != 0  
     
    begin  
     
       set @strTmp = '<(select min'  
     
    set @strOrder = ' order by ['+ @fldName +'] desc' 
     
    --如果@OrderType不是0,就执行降序,这句很重要!  
     
    end  
     
    else  
     
    begin  
     
       set @strTmp = '>(select max' 
     
       set @strOrder = ' order by ['+ @fldName +'] asc' 
     
    end  
     
     
     
    if @PageIndex = 1  
     
    begin  
     
       if @strWhere != ''    
     
        set @strSQL = 'select top ' + str(@PageSize) +' '+@strGetFields+ '  from ['+ @tblName +'] where ' + @strWhere + ' ' + @strOrder  
     
        else  
     
        set @strSQL = 'select top ' + str(@PageSize) +' '+@strGetFields+ '  from ['+ @tblName +'] '+ @strOrder  
     
    --如果是第一页就执行以上代码,这样会加快执行速度  
     
    end  
     
    else  
     
    begin  
     
    --以下代码赋予了@strSQL以真正执行的SQL代码  
     
    set @strSQL = 'select top ' + str(@PageSize) +' '+@strGetFields+ '  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) +' '+@strGetFields+ '  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) 
    GO 
      

  3.   

    /*分页查找数据*/ 
      CREATE PROCEDURE [dbo].[GetRecordSet] 
      @strSql varchar(8000),--查询sql,如select * from [user] 
      @PageIndex int,--查询当页号 
      @PageSize int--每页显示记录 
      AS 
      set nocount on 
      declare @p1 int 
      declare @currentPage int 
      set @currentPage = 0 
      declare @RowCount int 
      set @RowCount = 0 
      declare @PageCount int 
      set @PageCount = 0 
      exec sp_cursoropen @p1 output,@strSql,@scrollopt=1,@ccopt=1,@rowcount=@rowCount output --得到总记录数 
      select @PageCount=ceiling(1.0*@rowCount/@pagesize) --得到总页数 
      ,@currentPage=(@PageIndex-1)*@PageSize+1 
      select @RowCount,@PageCount 
      exec sp_cursorfetch @p1,16,@currentPage,@PageSize 
      exec sp_cursorclose @p1 
      set nocount off 
      GO本文来自CSDN博客,转载请标明出处:http://blog.csdn.net/fredrickhu/archive/2009/10/28/4740536.aspx
      

  4.   

    --1.无参存储过程
    --如果本班超过2人机试成绩未达到60分,则每人机试成绩提高2分,提分者不得超过100分
    /*--查看系统中是否存在'pro_stuMarks1',如果存在,删除,重建--*/
    if exists(select name from sysobjects where name='pro_stuMarks1')
    drop proc pro_stuMarks1
    go
    --创建'pro_stuMarks1'
    create proc pro_stuMarks1
    as
    while(1=1)
    begin
    if ((select count(*) from stuMarks where labExam<60)<2)
    begin
    break
    end
    else
    begin
    update stuMarks set labExam=labExam+2 where labExam<98
    end
    end
    go
    exec pro_stuMarks1  --调用存储过程
    select * from stuMarks--2.带参存储过程/*
    带参存储过程格式:
        create procedure 存储过程名(@参数名称 类型,...)
        as
            SQL语句
        go          
    调用方式:
    execute 存储过程名 参数值,...
    */
    --要求可传入分数底线if exists(select name from sysobjects where name='pro_stuMarks2')
    drop proc pro_stuMarks2
    go
    create proc pro_stuMarks2 @LabExam int
    as
    while(1=1)
    begin
    if ((select count(*) from stuMarks where labExam<@LabExam)<2)
    begin
    break
    end
    else
    begin
    update stuMarks set labExam=labExam+2 where labExam<98
    end
    end
    go
    exec pro_stuMarks2 70
    select * from stuMarks--4.带有输出参数的存储过程
    /*
    带有输出参数的存储过程格式:
    create procedure 存储过程名(@参数名称 类型 output,...)
        as
            SQL语句
            select @参数名=...
        go   
    调用格式:
    declaue @returnValue int
    exec 存储过程名 @returnValue output
    print '返回参数值为:' + convert(varchar(5), @returnValue)
    */
    --要求可以传入分数底线和人数,如果不给人数参数指定值,则默认为2,并返回提分后机试还未达到分数线的学生人数
    if exists(select name from sysobjects where name='pro_stuMarks5')
    drop proc pro_stuMarks5
    go
    create proc pro_stuMarks5(@score int,@count int output,@poplecount int=2)
    as
    if((select count(*) from stuMarks where labExam<@score)>@poplecount)
    begin
    update stuMarks set labExam=labExam+2
    set @count=(select count(*) from stuMarks where labExam<@score)
    end
    else
    set @count=0
    go
    --调用
    declare @count int
    exec pro_stuMarks5 60,@count output
    print '提分后还有'+convert(varchar(5),@count)+'人未达到分数底线'