求一个分页效率好的 存储过程
分页的实现代码 页面层如何调用
谢谢

解决方案 »

  1.   

    引用邹建的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
    BEGIN
    RAISERROR(N'对象"%s"不存在',1,16,@tbname)
    RETURN
    END
    IF OBJECTPROPERTY(OBJECT_ID(@tbname),N'IsTable')=0
    AND OBJECTPROPERTY(OBJECT_ID(@tbname),N'IsView')=0
    AND OBJECTPROPERTY(OBJECT_ID(@tbname),N'IsTableFunction')=0
    BEGIN
    RAISERROR(N'"%s"不是表、视图或者表值函数',1,16,@tbname)
    RETURN
    END--分页字段检查
    IF ISNULL(@FieldKey,N'')=''
    BEGIN
    RAISERROR(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''
    ELSE
    SET @FieldOrder=N'ORDER BY '+LTRIM(@FieldOrder)
    IF ISNULL(@Where,N'')=N''
    SET @Where=N''
    ELSE
    SET @Where=N'WHERE ('+@Where+N')'--如果@PageCount为NULL值,则计算总页数(这样设计可以只在第一次计算总页数,以后调用时,把总页数传回给存储过程,避免再次计算总页数,对于不想计算总页数的处理而言,可以给@PageCount赋值)
    IF @PageCount IS NULL
    BEGIN
    DECLARE @sql nvarchar(4000)
    SET @sql=N'SELECT @PageCount=COUNT(*)'
    +N' FROM '+@tbname
    +N' '+@Where
    EXEC sp_executesql @sql,N'@PageCount int OUTPUT',@PageCount OUTPUT
    SET @PageCount=(@PageCount+@PageSize-1)/@PageSize
    END--计算分页显示的TOPN值
    DECLARE @TopN varchar(20),@TopN1 varchar(20)
    SELECT @TopN=@PageSize,
    @TopN1=(@PageCurrent-1)*@PageSize--第一页直接显示
    IF @PageCurrent=1
    EXEC(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 sysname
    SELECT @Where1=N'',@Where2=N'',@s=@FieldKey
    WHILE CHARINDEX(N',',@s)>0
    SELECT @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=CASE
    WHEN @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
      

  2.   

    fengxin107(追逐彩虹)
    前台怎么调用
      

  3.   

    1.
     http://dev.csdn.net/develop/article/72/72126.shtm2.
    引用:CREATE procedure main_table_pwqzc
    (@pagesize int,
    @pageindex int,
    @docount bit,
    @this_id)
    as
    if(@docount=1)
    begin
    select count(id) from luntan where this_id=@this_id
    end
    else
    begin
    declare @indextable table(id int identity(1,1),nid int)
    declare @PageLowerBound int
    declare @PageUpperBound int
    set @PageLowerBound=(@pageindex-1)*@pagesize
    set @PageUpperBound=@PageLowerBound+@pagesize
    set rowcount @PageUpperBound
    insert into @indextable(nid) select id from luntan where this_id=@this_id order by reply_time desc
    select a.* from luntan a,@indextable t where a.id=t.nid
    and t.id>@PageLowerBound and t.id<=@PageUpperBound order by t.id
    end
    GO存储过程会根据传入的参数@docount来确定是不是要返回所有要分页的记录总数
    特别是这两行
    set rowcount @PageUpperBound
    insert into @indextable(nid) select id from luntan where this_id=@this_id order by reply_time desc真的是妙不可言!!set rowcount @PageUpperBound当记录数达到@PageUpperBound时就会停止处理查询
    ,select id 只把id列取出放到临时表里,select a.* from luntan a,@indextable t where a.id=t.nid
    and t.id>@PageLowerBound and t.id<=@PageUpperBound order by t.id
    而这句也只从表中取出所需要的记录,而不是所有的记录,结合起来,极大的提高了效率!!
    妙啊,真的妙!!!!
      

  4.   

    百万数据翻页就像100条数据一样
    ====================================================================CREATE PROCEDURE pageTest  --用于翻页的测试
    --需要把排序字段放在第一列 (
      @FirstID nvarchar(20)=null,  --当前页面里的第一条记录的排序字段的值
      @LastID nvarchar(20)=null,  --当前页面里的最后一条记录的排序字段的值
      @isNext bit=null,    --true 1 :下一页;false 0:上一页
      @allCount int output,   --返回总记录数
      @pageSize int output,   --返回一页的记录数
      @CurPage int     --页号(第几页)0:第一页;-1最后一页。
      )ASif @CurPage=0
     begin
      --统计总记录数
      select @allCount=count(ProductId) from Product_test 
       
      set @pageSize=10
      --返回第一页的数据
      select top 10 
       ProductId,
       ProductName,
       Introduction   
       from Product_test order by ProductId 
     endelse if @CurPage=-1 select * from 
      (select top 10 ProductId,
       ProductName,
       Introduction  from Product_test order by ProductId desc ) as aa  
      order by ProductId
    else begin 
      if @isNext=1
       --翻到下一页
       select top 10 ProductId,
       ProductName,
       Introduction
      from Product_test where ProductId > @LastID order by ProductId 
       
       
      else
       --翻到上一页
       select * from
        (select top 10 ProductId,
       ProductName,
       Introduction
      from Product_test where ProductId < @FirstID  order by ProductId desc) as bb order by ProductId
     end
      

  5.   

    我这是前台调用存储过程的代码,用的是我自己的分页存储过程,你用别的存储过程,改下参数就是了
    public static DataSet Pages(string TableName,string PrimaryKey,int PageSize,int PageCurrent,string ShowList,
    string OrderCol,int OrderType,string Condition)//支持条件
    {
    SqlConnection myConnection = new SqlConnection(strConnection);
    SqlCommand myCommand = new SqlCommand("pages",myConnection);

    myCommand.CommandType = CommandType.StoredProcedure; SqlParameter paraTableName = new SqlParameter("@TableName",SqlDbType.VarChar,100);
    paraTableName.Value = TableName;//表名
    myCommand.Parameters.Add(paraTableName); SqlParameter paraPrimaryKey = new SqlParameter("@PrimaryKey",SqlDbType.VarChar,50);
    paraPrimaryKey.Value = PrimaryKey;//该表的主键
    myCommand.Parameters.Add(paraPrimaryKey);

    SqlParameter paraPageSize = new SqlParameter("@PageSize",SqlDbType.Int,4);
    paraPageSize.Value = PageSize;//  --每页记录数
    myCommand.Parameters.Add(paraPageSize);

    SqlParameter paraPage = new SqlParameter("@PageCurrent",SqlDbType.Int,4);
    paraPage.Value = PageCurrent;//--指定页
    myCommand.Parameters.Add(paraPage);

    SqlParameter paraShowList = new SqlParameter("@ShowList",SqlDbType.VarChar,500);
    paraShowList.Value = ShowList;//--要查询出的字段列表,*表示全部字段
    myCommand.Parameters.Add(paraShowList); SqlParameter paraOrderCol = new SqlParameter("@OrderCol",SqlDbType.VarChar,50);
    paraOrderCol.Value = OrderCol;// --@col列的类型,0-数字类型,1-字符类型,2-日期时间类型
    myCommand.Parameters.Add(paraOrderCol); SqlParameter paraOrderType = new SqlParameter("@OrderType",SqlDbType.Int,4);
    paraOrderType.Value = OrderType;//   --排序,0-顺序,1-倒序
    myCommand.Parameters.Add(paraOrderType);          

    SqlParameter paraCondition = new SqlParameter("@where",SqlDbType.VarChar,800);
    paraCondition.Value =Condition; //指定查询条件
    myCommand.Parameters.Add(paraCondition); SqlDataAdapter adapter = new SqlDataAdapter();
    adapter.SelectCommand = myCommand; DataSet ds = new DataSet(); myConnection.Open();
    adapter.SelectCommand.ExecuteNonQuery();
    myConnection.Close(); adapter.Fill(ds,"Table"); return ds;
    }