zoukankan      html  css  js  c++  java
  • SQL Server的通用分页存储过程 未使用游标,速度更快!

    经过一个下午的时间,和我一个同事(绝对是高手)的共同努力下,摸索出了以下的思路: 

    1、确定存储的输入参数: 
    1)SQL脚本,该参数接收完整的、正确的SQL检索文本,可将原应用中写好的SQL脚本直接传入 
    2)每页的数据容量,就是一页有多少条数据 
    3)当前页码 
    2、确定分页机制: 
    1)执行传入的SQL脚本,并将结果生成临时表 
    2)修改临时表的结构,增加标识列字段 
    3)根据标识列字段,计算出指定页码内的记录范围,并返回 
    4)返回总数据条数,用于客户端进行分页显示 

    根据以上的思路,编写出以下通用的分页存储过程: 

    复制代码代码如下:

    [code] 
    --// ============================ 
    --// SQL Server通用分页存储过程 
    --// Author : netwild 
    --// date : 2010/07/22 
    --// Email : netwild@163.com 
    --// QQ : 52100641(网无忌) 
    --// ============================ 

    SET QUOTED_IDENTIFIER ON 
    GO 
    SET ANSI_NULLS ON 
    GO 


    CREATE PROC execByPage 

    @sqlQuery varchar(2000), --//输入参数:SQL检索语句或表名 
    @pageSize int, --//输入参数:每页显示记录条数 
    @pageIndex int --//输入参数:当前页码 

    AS 

    SET NOCOUNT ON 
    SET ANSI_WARNINGS OFF 

    declare @tmpTableName varchar(50) 
    set @tmpTableName = '##TB1516_' + replace(cast(newid() as varchar(40)),'-','') --//生成随机临时表名称 

    declare @subIndex int 
    set @subIndex = charindex('from',@sqlQuery) 
    if (@subIndex > 0) 
    begin --//带FROM的标准检索语句 
    declare @sqlQuery1 varchar(2000) 
    declare @sqlQuery2 varchar(2000) 
    set @sqlQuery1 = substring(@sqlQuery,1,@subIndex - 1) 
    set @sqlQuery2 = substring(@sqlQuery,@subIndex,len(@sqlQuery)) 
    set @sqlQuery = @sqlQuery1 + ',IDENTITY(numeric,1,1) as ID1516 into ' + @tmpTableName + ' ' + @sqlQuery2 
    end 
    else --//不带FROM的表名 
    begin 
    set @sqlQuery = 'select *,IDENTITY(numeric,1,1) as ID1516 into ' + @tmpTableName + ' from' + @sqlQuery 
    end 
    exec(@sqlQuery) --//建立并初始化临时表数据 

    declare @indexStart varchar(20),@indexEnd varchar(20) 
    set @indexStart = cast((@pageIndex-1)*@pageSize+1 as varchar(20)) --//数据起始行ID 
    set @indexEnd = cast(@pageIndex * @pageSize as varchar(20)) --//数据结束行ID 

    exec('select * from ' + @tmpTableName + ' where ID1516 between ' + @indexStart + ' and ' + @indexEnd) --//检索该页数据 

    exec('select max(ID1516) as recordCount from ' + @tmpTableName) --//提取总条数 

    exec('drop table ' + @tmpTableName) --//删除临时表 


    GO 
    SET QUOTED_IDENTIFIER OFF 
    GO 
    SET ANSI_NULLS ON 
    GO 
     

    C#中常用的分页存储过程小结

    表中主键必须为标识列,[ID] int IDENTITY (1,1)//每次自增一 
    1.分页方案一:(利用Not In和SELECT TOP分页) 
    语句形式: 

    复制代码代码如下:

    SELECT TOP 10 * 
    FROM TestTable 
    WHERE (ID NOT IN 
    (SELECT TOP 20 id 
    FROM TestTable 
    ORDER BY id)) 
    ORDER BY ID 


    SELECT TOP 页大小 * 
    FROM TestTable 
    WHERE (ID NOT IN 
    (SELECT TOP 页大小*页数 id 
    FROM 表 
    ORDER BY id)) 
    ORDER BY ID 


    2.分页方案二:(利用ID大于多少和SELECT TOP分页) 
    语句形式: 

    复制代码代码如下:

    SELECT TOP 10 * 
    FROM TestTable 
    WHERE (ID > 
    (SELECT MAX(id) 
    FROM (SELECT TOP 20 id 
    FROM TestTable 
    ORDER BY id) AS T)) 
    ORDER BY ID 


    SELECT TOP 页大小 * 
    FROM TestTable 
    WHERE (ID > 
    (SELECT MAX(id) 
    FROM (SELECT TOP 页大小*页数 id 
    FROM 表 
    ORDER BY id) AS T)) 
    ORDER BY ID 


    3.分页方案三:(利用SQL的游标存储过程分页) 

    复制代码代码如下:

    create procedure SqlPager 
    @sqlstr nvarchar(4000), --查询字符串 
    @currentpage int, --第N页 
    @pagesize int --每页行数 
    as 
    set nocount on 
    declare @P1 int, --P1是游标的id 
    @rowcount int 
    exec sp_cursoropen @P1 output,@sqlstr,@scrollopt=1,@ccopt=1, @rowcount=@rowcount output 
    select ceiling(1.0*@rowcount/@pagesize) as 总页数--,@rowcount as 总行数,@currentpage as 当前页 
    set @currentpage=(@currentpage-1)*@pagesize+1 
    exec sp_cursorfetch @P1,16,@currentpage,@pagesize 
    exec sp_cursorclose @P1 
    set nocount off 


    4. 

    复制代码代码如下:

    CREATE Procedure FramWorkPage 
    @TableName varchar(50), --表名 
    @Fields varchar(5000) = '*', --字段名(全部字段为*) 
    @OrderField varchar(5000), --排序字段(必须!支持多字段) 
    @sqlWhere varchar(5000) = Null,--条件语句(不用加where) 
    @pageSize int, --每页多少条记录 
    @pageIndex int = 1 , --指定当前为第几页 
    @TotalPage int output, --返回条数 
    @OrderType bit -- 设置排序类型,1 升序 0 值则降序 
    as 
    begin 
    declare @strOrder varchar(400) -- 排序类型 

    Begin Tran --开始事务 
    Declare @sql nvarchar(4000); 
    Declare @totalRecord int; 
    --计算总记录数 
    if (@SqlWhere ='''' or @SqlWhere='' or @sqlWhere is NULL) 
    set @sql = 'select @totalRecord = count(*) from ' + @TableName 
    else 
    set @sql = 'select @totalRecord = count(*) from ' + @TableName + ' where ' + @sqlWhere 
    EXEC sp_executesql @sql,N'@totalRecord int OUTPUT',@totalRecord OUTPUT--计算总记录数

    --计算总页数 

    select @TotalPage=@totalRecord --CEILING((@totalRecord+0.0)/@PageSize) 

    if @OrderType = 0 
    begin 
    set @strOrder = ' order by [' + @OrderField +'] desc' 
    --如果@OrderType是0,就执行降序,这句很重要! 
    end 
    else 
    begin 
    set @strOrder = ' order by [' + @OrderField +'] asc' 
    end 

    if (@SqlWhere ='''' or @SqlWhere='' or @sqlWhere is NULL) 
    set @sql = 'Select * FROM (select ROW_NUMBER() Over( '+@strOrder+' ) as rowId,' + @Fields + ' from ' + @TableName 
    else 
    set @sql = 'Select * FROM (select ROW_NUMBER() Over( '+@strOrder+' ) as rowId,' + @Fields + ' from ' + @TableName + ' where ' + @SqlWhere 
    --处理页数超出范围情况 
    if @PageIndex<=0 
    Set @pageIndex = 1 

    if @pageIndex>@TotalPage 
    Set @pageIndex = @TotalPage 

    --处理开始点和结束点 
    Declare @StartRecord int 
    Declare @EndRecord int 

    set @StartRecord = (@pageIndex-1)*@PageSize + 1 
    set @EndRecord = @StartRecord + @pageSize - 1 

    if @OrderType = 0 
    begin 
    set @strOrder = ' order by rowid desc' 
    --如果@OrderType是0,就执行降序,这句很重要! 
    end 
    else 
    begin 
    set @strOrder = ' order by rowid asc' 
    end 
    --继续合成sql语句 
    set @Sql = @Sql + ') as ' + @TableName + ' where rowId between ' + Convert(varchar(50),@StartRecord) + ' and ' + Convert(varchar(50),@EndRecord) + ' '+@strOrder 
    -- print @sql 
    Exec(@Sql) 
    --------------------------------------------------- 
    If @@Error <> 0 
    Begin 
    RollBack Tran 
    Return -1 
    End 
    Else 
    Begin 
    Commit Tran 
    Return @totalRecord ---返回记录总数 
    End 
    end 
  • 相关阅读:
    徒手画个disk不容易啊。。。
    fast powf
    SSE sqrt还是比C math库的sqrtf快了不少
    Mongoose也是个大坑
    A tiny program to benchmark image transpose algorithms
    On extracting ops from LLVM backend
    Into concurrent LRU caching once again
    性能大坑
    多项式在线拟合神器
    Spark 1.6.1源码编译
  • 原文地址:https://www.cnblogs.com/mili3/p/3558194.html
Copyright © 2011-2022 走看看