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

    使用SQL Server时,分页处理一直是个比较棘手的问题

    正常情况下,SQL Server服务器上会对使用频率大的Table建立合适的索引

    这样能大幅度的提高数据库本身的数据检索速度,建立索引的方法就不细说了

    如果需要返回大量数据,从几百行到几万行,甚至几十万行数据

    这时会发现响应速度越来越慢,甚至发生响应超时的错误

    为了解决这种大数据量请求的问题,就不得不使用分页模式了

    在这方面,JDBC就强悍得多,它可以将指定的行数和SQL请求一并发送给SQL Server,这样只返回分页后的数据,JDBC的原理还不清楚,但在实际使用中,速度还是非常快的

    如果没办法使用JDBC,最常用的方法就是存储过程了!

    我在写这个分页存储之前,参考了网上的大量相关文章,可以通过关键字:SQL Server 分页 进行搜索

    他们主要都是利用SQL中的Top方法,并且对所检索的数据结构要求有标识列,如果没有标识列,或者是联合主键,那么就会非常麻烦了。而且对应用里原有的SQL检索部分需要修改的地方较多,工作量较大。

    因此,我在写这个存储之前就要求一定要对原有的SQL脚本最大程度的兼容

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

    1、确定存储的输入参数:

    1)SQL脚本,该参数接收完整的、正确的SQL检索文本,可将原应用中写好的SQL脚本直接传入

    2)每页的数据容量,就是一页有多少条数据

    3)当前页码

    2、确定分页机制:

    1)执行传入的SQL脚本,并将结果生成临时表

    2)修改临时表的结构,增加标识列字段

    3)根据标识列字段,计算出指定页码内的记录范围,并返回

    4)返回总数据条数,用于客户端进行分页显示

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

     1 --// ============================   
     2 --// SQL Server通用分页存储过程   
     3 --// Author : netwild   
     4 --// date : 2010/07/22   
     5 --// Email : netwild@163.com   
     6 --// QQ : 52100641(网无忌)   
     7 --// ============================   
     8    
     9  SET QUOTED_IDENTIFIER ON    
    10  GO   
    11  SET ANSI_NULLS ON    
    12  GO   
    13   
    14   
    15  CREATE PROC execByPage   
    16   
    17  @sqlQuery varchar(2000), --//输入参数:SQL检索语句或表名   
    18   @pageSize int--//输入参数:每页显示记录条数   
    19   @pageIndex int --//输入参数:当前页码   
    20    
    21  AS   
    22   
    23  SET NOCOUNT ON   
    24 SET ANSI_WARNINGS OFF    
    25   
    26 declare @tmpTableName varchar(50)   
    27 set @tmpTableName = '##TB1516_' + replace(cast(newid() as varchar(40)),'-',''--//生成随机临时表名称   
    28   
    29 declare @subIndex int   
    30 set @subIndex = charindex('from',@sqlQuery)    
    31 if (@subIndex > 0)   
    32 begin --//带FROM的标准检索语句   
    33     declare @sqlQuery1 varchar(2000)   
    34     declare @sqlQuery2 varchar(2000)   
    35     set @sqlQuery1 = substring(@sqlQuery,1,@subIndex - 1)   
    36     set @sqlQuery2 = substring(@sqlQuery,@subIndex,len(@sqlQuery))   
    37     set @sqlQuery = @sqlQuery1 + ',IDENTITY(numeric,1,1) as ID1516 into ' + @tmpTableName + ' ' + @sqlQuery2   
    38 end   
    39 else --//不带FROM的表名   
    40 begin   
    41     set @sqlQuery = 'select *,IDENTITY(numeric,1,1) as ID1516 into ' + @tmpTableName + ' from' + @sqlQuery   
    42 end   
    43 exec(@sqlQuery--//建立并初始化临时表数据   
    44   
    45 declare @indexStart varchar(20),@indexEnd varchar(20)   
    46 set @indexStart = cast((@pageIndex-1)*@pageSize+1 as varchar(20)) --//数据起始行ID   
    47 set @indexEnd = cast(@pageIndex * @pageSize as varchar(20)) --//数据结束行ID   
    48   
    49 exec('select * from ' + @tmpTableName + ' where ID1516 between ' + @indexStart + ' and ' + @indexEnd--//检索该页数据   
    50   
    51 exec('select max(ID1516) as recordCount from ' + @tmpTableName--//提取总条数   
    52   
    53 exec('drop table ' + @tmpTableName--//删除临时表   
    54   
    55   
    56 GO   
    57 SET QUOTED_IDENTIFIER OFF    
    58 GO   
    59 SET ANSI_NULLS ON    
    60 GO   
  • 相关阅读:
    java 深入技术三(List)
    java 深入技术二(Collection)
    java开发JDBC连接数据库详解
    数据库基础和JDBC
    java 深入技术一
    java入门 第三季4
    java入门 第三季3
    04-1. 水仙花数(20)
    04-0. 求符合给定条件的整数集(15)
    03-4. 成绩转换(15)
  • 原文地址:https://www.cnblogs.com/netWild/p/1892360.html
Copyright © 2011-2022 走看看