zoukankan      html  css  js  c++  java
  • 存储过程分页

     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]
    GO

    CREATE 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-1as 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

    ------------------------------------
    --用途:分页存储过程(对有主键的表效率极高)
    --说明:
    ------------------------------------

    CREATE PROCEDURE UP_GetRecordByPage
        @tblName      varchar(
    255),       -- 表名
        @fldName      varchar(
    255),       -- 主键字段名
        @PageSize    
    int=10,           -- 页尺寸
        @PageIndex   
    int=1,            -- 页码
        @IsReCount    bit
    =0,            -- 返回记录总数, 非 0 值则返回
        @OrderType    bit
    =0,            -- 设置排序类型, 非 0 值则降序
        @strWhere     varchar(
    1000) =''  -- 查询条件 (注意: 不要加 where)
    AS

    declare @strSQL   varchar(
    6000)       -- 主语句
    declare @strTmp   varchar(
    100)        -- 临时变量
    declare @strOrder varchar(
    400)        -- 排序类型

    if @OrderType !=0
    begin
       
    set @strTmp ='<(select min'
       
    set @strOrder =' order by ['+ @fldName +'] desc'
    end
    else
    begin
       
    set @strTmp ='>(select max'
       
    set @strOrder =' order by ['+ @fldName +'] asc'
    end

    set @strSQL ='select top '+ str(@PageSize) +' * 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) +' * from ['
           
    + @tblName +'] where ['+ @fldName +']'+ @strTmp +'(['
           
    + @fldName +']) from (select top '+ str((@PageIndex-1)*@PageSize) +' ['
           
    + @fldName +'] from ['+ @tblName +'] where '+ @strWhere +''
           
    + @strOrder +') as tblTmp) and '+ @strWhere +''+ @strOrder

    if @PageIndex =1
    begin
       
    set @strTmp =''
       
    if @strWhere !=''
           
    set @strTmp =' where '+ @strWhere

       
    set @strSQL ='select top '+ str(@PageSize) +' * from ['
           
    + @tblName +']'+ @strTmp +''+ @strOrder
    end

    if @IsReCount !=0
       
    set @strSQL ='select count(*) as Total from ['+ @tblName +']'+' where '+ @strWhere

    exec (@strSQL)

    GO

    存储过程:

    create proc Test

    @PageIndex INT,--@PageIndex从计数,0为第一页

    @PageSize INT, --页面大小

    @RecordCount INT OUT, --总记录数

    @PageCount INT OUT--页数

    as

    SELECT @RecordCount = COUNT(*) FROM A --获取记录数 SET @PageCount = CEILING(@RecordCount * 1.0 / @PageSize) --计算页面数据

    SELECT SerialNumber,Id,Names,Age FROM (SELECT Id,Names,Age,ROW_NUMBER() OVER (ORDER BY Id )  AS SerialNumber FROM A ) AS T

    WHERE T.SerialNumber > (@PageIndex * @PageSize) and T.SerialNumber <= ((@PageIndex+1) * @PageSize)

    go

    存储过程测试:

    DECLARE @RecordCount int ,@PageCount int exec Test 0,10, @RecordCount  OUTPUT, @PageCount  OUTPUT select @RecordCount,@PageCount go

    存储过程的调用:
    -----已更新---
    DBHelper类中的方法:
            /// <summary>
            /// sql带返回参数的存储过程(分页)
            /// </summary>
            /// <param name="procName">存储过程名字</param>
            /// <param name="outParameterName">输出参数的名字</param>
            /// <param name="dic">输出参数得到的值</param>
            /// <param name="pars">参数列表</param>
            /// <returns>DataTable</returns>
            public static DataTable GetFillData(string procName,string [] outParameterName, out Dictionary<string,object> dic,params SqlParameter[] pars)
            {
                Dictionary<string, object> dictionary = new Dictionary<string, object>();
                DataSet ds = new DataSet();
                using (cmd = new SqlCommand(procName, Connectionstrings))
                {
                    cmd.CommandType = CommandType.StoredProcedure;
                    cmd.Parameters.AddRange(pars);
                    foreach (var item in outParameterName)
                    {
                        cmd.Parameters[item].Direction = ParameterDirection.Output;
                    }
                    using (adapter = new SqlDataAdapter(cmd))
                    {
                        adapter.Fill(ds);
                        dic = dictionary;
                        foreach (var item in outParameterName)
                        {
                            dictionary.Add(item, cmd.Parameters[item].Value.ToString());
                        }
                        return ds.Tables[0];
                    }
                }
            }
    DBHelper类可能大家的都不同,可以根据自己的DBHelper类修改此方法。 在这里我也把自己用的DBHelper写出来(注重版权,本人只是交流需要,无其他商业目的)

       

         

          

           

         

          

         

           

         

          

           

  • 相关阅读:
    008Spring & JPA & Hibernate & MySQL
    007Spring Security
    006Spring面向切面
    005运行时值注入
    004bean作用域
    003自动装配歧义性解决
    002Conditional条件化创建bean
    001profile条件化创建bean
    007API网关服务Zuul
    Sqlserver2008R2 如何使用bak备份文件还原数据库以及对应的失败解决方案
  • 原文地址:https://www.cnblogs.com/xu3593/p/2821585.html
Copyright © 2011-2022 走看看