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 
  • 相关阅读:
    fedora上部署ASP.NET——(卡带式电脑跑.NET WEB服务器)
    SQL Server 请求失败或服务未及时响应。有关详细信息,请参见事件日志或其它适合的错误日志
    8086CPU的出栈(pop)和入栈(push) 都是以字为单位进行的
    FTP 服务搭建后不能访问问题解决
    指定的 DSN 中,驱动程序和应用程序之间的体系结构不匹配
    Linux 安装MongoDB 并设置防火墙,使用远程客户端访问
    svn Please execute the 'Cleanup' command. 问题解决
    .net 操作MongoDB 基础
    oracle 使用绑定变量极大的提升性能
    尝试加载 Oracle 客户端库时引发 BadImageFormatException。如果在安装 32 位 Oracle 客户端组件的情况下以 64 位模式运行,将出现此问题。
  • 原文地址:https://www.cnblogs.com/mili3/p/3558194.html
Copyright © 2011-2022 走看看