`
fly533
  • 浏览: 109340 次
  • 性别: Icon_minigender_1
  • 来自: 广西
社区版块
存档分类
最新评论

通用数据分页存储过程

阅读更多
目前基于Sql语句的分页算法已经比较普及,但查询最后N页的时候速度普遍缓慢.支持MS SqlServer.

--------------------------------------- 
--名称:fn_IsNull 
--描述:参数空值判断,可包括:字符串,整型,VARBINARY等是否为空的判断 
--输入:参数 
--输出:无 
--返回:是否为空标志,输出类型为bit,0表示不为空,1表示为空 
--------------------------------------- 
CREATE FUNCTION [dbo].[fn_IsNull] 
( 
@psStr NVARCHAR(1000) --字符串 
) 
RETURNS BIT 
AS 
BEGIN 
   DECLARE @tFlag bit   
   IF (@psStr IS NULL) OR (LEN(@psStr)=0) 
       SET @tFlag=1 
   ELSE 
       SET @tFlag=0 
   RETURN @tFlag 
END 



------------------------------------- 
-- 
-- 数据通用分页 
-- 
------------------------------------- 
CREATE            PROCEDURE dbo.sp_General_Pagination 
@psTblName         VARCHAR(1000) = NULL, -- 设置表名 
@psStrGetFields    VARCHAR(200) = '*' , -- 设置需要返回的列名 
@psFidName         VARCHAR(255)  = NULL, -- 设置排序的字段名 
@psPageSize        INT = 10,              -- 设置分页尺寸,必须大于0 
@psPageIndex       INT = 1,               -- 设置分页码,必须大于0 
@psOrderType       BIT = 0,               -- 设置排序类型, 非0非空值则降序 
@psStrWhere        VARCHAR(2500) = NULL, -- 设置查询条件(注:不要加WHERE) 
@rsPageCount    INT = 0 OUTPUT,        -- 输出页数 
@rsRecordCount     INT = 0 OUTPUT         -- 输出记录总数 
AS 
BEGIN 
    SET NOCOUNT ON 
-- 参数合法性检查 
IF ( 
             (dbo.fn_IsNull(@psTblName)= 1)         -- 判断表名为空时返回 
     OR (dbo.fn_IsNull(@psFidName) = 1)     -- 判断排序字段为空时返回 
     OR (dbo.fn_IsNull(@psPageIndex) = 1)   -- 判断分页尺寸为空时返回 
     OR (dbo.fn_IsNull(@psPageSize) = 1)    -- 判断分页码为空时返回 
     OR (@psPageIndex <= 0)                    -- 如果分页尺寸小于等于0,返回 
     OR (@psPageSize <= 0)                -- 如果分页码小于等于0,返回  
   ) 
        BEGIN 
        RETURN 0 
END 
-- 判断返回列名字段为空时设置为'*' 
IF (dbo.fn_IsNull(@psStrGetFields)= 1) 
BEGIN 
SET @psStrGetFields = '*' 
END 
        IF (dbo.fn_IsNull(@psStrWhere)= 1) 
        BEGIN 
SET @psStrWhere = '' 
END 

-- 定义参数 
DECLARE @strNSQL        NVARCHAR(4000) -- 主语句 
DECLARE @strSQL         VARCHAR(8000)  -- 主语句 
DECLARE @strTmp         VARCHAR(20)    -- 临时变量 
DECLARE @strParams      VARCHAR(500)   -- 参数值 
DECLARE @strOrder       VARCHAR(200)   -- 排序类型 
        DECLARE @strPageSize    VARCHAR(10)    --页大小 
        DECLARE @strTopPageSize    VARCHAR(10) --转换后的页大小 
        DECLARE @strMaxTmp     VARCHAR(8000) 
        --参数初始化         
        SET @strNSQL='' 
SET @strSQL='' 
SET @strTmp='' 
SET @strParams='' 
SET @strOrder='' 
        SET @strPageSize='' 
        SET @strTopPageSize='' 
        SET @strMaxTmp='' 
        SET  @strMaxTmp='' --必要 
  
----- END 
             
        -- 计算总记录数(OUTPUT参数) 
IF (dbo.fn_IsNull(@psStrWhere)= 0) -- 判断是否有条件语句 
BEGIN                 
SET @strNSQL = 'SELECT @rsRecordCount = COUNT(1)'+CHAR(10)+' FROM ' + @psTblName 
      +CHAR(10)+ ' WHERE ' + @psStrWhere+CHAR(10) 
END 
ELSE 
BEGIN 
SET @strNSQL = 'SELECT @rsRecordCount = COUNT(1)'+CHAR(10)+' FROM ' + @psTblName+CHAR(10) 
END 

    --PRINT @strNSQL 
        
    -- 执行SQL语句,求出总记录数 
EXEC sp_executesql @strNSQL, N'@rsRecordCount INT OUTPUT',@rsRecordCount OUTPUT 
IF @@ERROR <> 0 
BEGIN 
RETURN 0 
END 
-- 计算总页数(OUTPUT参数) 
SET @rsPageCount =CEILING( @rsRecordCount*1.0 / @psPageSize) 

        -- 如果总页数为0,直接返回 
IF (@rsRecordCount = 0) 
BEGIN 
EXEC ('SELECT ' + @psStrGetFields + ' FROM '+ @psTblName + ' WHERE 1<>1') 
IF @@ERROR <> 0 
        BEGIN 
RETURN 0 
END    
ELSE 
        BEGIN 
       RETURN 1 
        END 
END 

--如果分页码大于总页数则把分页码置为总页数,表示取最后一页 
        IF (@psPageIndex>@rsPageCount) AND (@rsPageCount>0) 
        BEGIN 
            SET @psPageIndex=@rsPageCount 
        END  
        --如果页大小超过总页数,自动纠正  
        IF(@psPageSize>@rsRecordCount) 
        BEGIN 
            SET @psPageSize=@rsRecordCount 
        END  

        -- 把页大小转换为字符串 
SET @strPageSize= CONVERT(varchar(10),@psPageSize) 
        SET @strTopPageSize=@strPageSize 
        
        DECLARE @tReverseFlag INT 
        --如果当前页不是第一页,且大等于总页数的一半,才需要倒过来处理 
        IF(@psPageIndex>1 AND  @psPageIndex>@rsPageCount*1.0/2) 
        BEGIN 
             SET @tReverseFlag=1 
             SET @psPageIndex=@rsPageCount-@psPageIndex+1          
        END 
        ELSE 
        BEGIN 
             SET @tReverseFlag=0 
        END 
        
       --保证@psOrderType有确定的值好作位运算 
       IF(dbo.fn_IsNull(@psOrderType)= 1) 
       BEGIN 
           SET @psOrderType=0 
       END 
       IF(@psOrderType!=0) 
       BEGIN 
           SET @psOrderType=1 
       END 
        --根据位运算结果来判断是该升序还是降序 
        IF (@psOrderType ^ @tReverseFlag=1) 
			BEGIN   --需要降序处理 
			SET @strTmp = ' < ' 
			SET @strParams = 'MIN' 
			SET @strOrder = ' ORDER BY ' + @psFidName + ' DESC' 
			END 
			ELSE   
			BEGIN    --需要升序处理 
			SET @strTmp = ' > ' 
			SET @strParams = 'MAX' 
			SET @strOrder = ' ORDER BY ' + @psFidName + ' ASC' 
			END 

-- 主语句 
IF @psPageIndex = 1 -- 如果是第一页就加速执行 
BEGIN 
                --如果被转换且未被整除 
                IF(@tReverseFlag=1 AND @rsRecordCount % @psPageSize<>0) 
                BEGIN 
                     SET @strTopPageSize=CONVERT(VARCHAR(10),@rsRecordCount % @psPageSize) 
                END 

-- 判断是否有条件语句 
IF (dbo.fn_IsNull(@psStrWhere)=0) 
BEGIN 
SET @strSQL = 'SELECT TOP ' + @strTopPageSize + ' ' + @psStrGetFields 
+ CHAR(10) + ' FROM ' + @psTblName 
+ CHAR(10) + ' WHERE '                                
END 
ELSE 
BEGIN 
SET @strSQL = 'SELECT TOP ' + @strTopPageSize + ' ' + @psStrGetFields 
+ CHAR(10)+' FROM ' + @psTblName                                
END 
                
END 
ELSE -- 否则不是第一页就执行以下步骤 
BEGIN           
                SET @strTopPageSize=CONVERT(VARCHAR(10),(@psPageIndex-1)*@psPageSize) 
                 --如果被转换且未被整除 
                IF(@tReverseFlag=1) AND ( @rsRecordCount % @psPageSize<>0) 
                BEGIN -- 
                     SET @strTopPageSize=CONVERT(VARCHAR(10),(@psPageIndex-1)*@psPageSize-(@psPageSize-@rsRecordCount % @psPageSize))               
                END 
              
SET @strMaxTmp = 'DECLARE @strTmp VARCHAR(500) '+CHAR(10) 
+ 'SELECT @strTmp = ' + @strParams + '(' + @psFidName + ') FROM (SELECT TOP ' 
+ @strTopPageSize+' ' +  @psFidName + ' FROM ' + @psTblName 

-- 判断是否有条件语句 
                
IF (dbo.fn_IsNull(@psStrWhere)=0) -- 如果有条件语句就执行这一步 
BEGIN 

SET @strMaxTmp = @strMaxTmp + ' WHERE ' + @psStrWhere + ' ' + @strOrder + ') AS tblTmp '+CHAR(10) 
SET @strSQL= 'SELECT TOP ' + @strPageSize + ' ' + @psStrGetFields 
+ CHAR(10) +' FROM ' + @psTblName  
+ CHAR(10) +' WHERE ' + @psFidName + '' + @strTmp + '@strTmp AND ' 
END 
ELSE -- 如果没有条件语句就执行这一步 
BEGIN 

SET @strMaxTmp = @strMaxTmp + @strOrder + ') AS tblTmp '+CHAR(10) 
SET @strSQL= 'SELECT TOP ' + @strPageSize + ' ' + @psStrGetFields 
+ CHAR(10) +' FROM ' + @psTblName  
+ CHAR(10) +' WHERE ' + @psFidName + '' + @strTmp + '@strTmp ' 
END 
               
END 

------------- 
        SET @strSQL=@strSQL +@psStrWhere+ CHAR(10)+@strOrder 
        --如果已经进行转换,结果的排序还要倒换过来  
        IF(@tReverseFlag=1) 
        BEGIN 
              SET @strSQL='SELECT  '+@psStrGetFields+',IDENTITY(int,1,1) AS OrderField INTO #tmptbl  FROM ('+@strSQL + ') AS tbl800'+ CHAR(10)      
              SET @strSQL=@strSQL+'SELECT '+@psStrGetFields+' FROM #tmptbl ORDER BY OrderField DESC;DROP TABLE #tmptbl;' 
        END 
        
-- 执行SQL语句,求出数据集 
        --PRINT @strMaxTmp+@strSQL 
        EXEC  (@strMaxTmp+@strSQL) 
        IF @@ERROR <> 0  
        BEGIN 
RETURN 0 
        END    
ELSE 
        BEGIN 
       RETURN 1 
        END 

END 



GO 


分享到:
评论

相关推荐

    通用分页存储过程

    ### 通用分页存储过程知识点解析 #### 一、存储过程概述 在数据库管理系统中,...综上所述,通用分页存储过程为数据库中的数据分页提供了一个高效、灵活且易于使用的解决方案,能够极大地提高开发效率和用户体验。

    千万级分页存储过程 实现对表的数据分页 速度非常快

    本文将深入解析“千万级分页存储过程实现对表的数据分页速度非常快”的核心知识点,包括其原理、实现方法以及SQL Server中的具体应用。 ### 一、千万级分页存储过程的核心原理 在处理海量数据时,传统的全表扫描或...

    通用分页存储过程+通用分页存储过程

    根据提供的文件信息,我们可以了解到这段代码是用于创建一个SQL Server中的通用分页存储过程,名为`pagination3`。此存储过程旨在提供一种灵活且高效的方式来处理数据库查询中的分页问题,使得开发人员能够轻松地在...

    最通用的分页存储过程

    最通用的分页存储过程 获取指定页的数据 支持多表查询支持条件查询 支持排序--支持返回列自定义

    Oracle通用数据库存储过程代码--高效分页存储过程

    ### Oracle通用数据库存储过程代码——高效分页存储过程解析 #### 标题解析 标题“Oracle通用数据库存储过程代码——高效分页存储过程”表明这是一个适用于Oracle数据库的存储过程,主要用于实现高效的分页查询功能...

    mysql存储过程通用分页

    MySQL存储过程是数据库管理系统中的一种重要功能,它允许开发者编写一系列复杂的SQL语句,...同时,结合标签“源码”和“工具”,可能还涉及到如何将这些存储过程集成到开发工具或脚本中,以自动化处理数据分页的工作。

    web中通用分页存储过程

    web中通用分页存储过程,是根据PageIndex来取得相应的页数据,并不是上下翻页,对单字段,多字段均适用,并在百万级数据上测试,分页速度较好。

    万能分页存储过程

    万能分页存储过程之所以被称为“万能”,是因为它应该具备足够的灵活性和通用性,能够适应各种表结构和查询需求,而不局限于特定的场景或数据模型。 首先,我们来理解分页的基本原理。分页查询通常涉及到两个关键...

    几款通用的sql分页存储过程

    ### 几款通用的SQL分页存储过程:深入解析与应用 在数据库操作中,分页查询是一项常见的需求,尤其当数据量庞大时,合理的分页可以极大地提高查询效率和用户体验。本文将深入分析两款通用的SQL分页存储过程,分别...

    通用的SQL server分页存储过程

    标题提到的“通用的SQL server分页存储过程”提供了一种解决方案,可以避免重复编写存储过程,只需调整参数即可满足不同分页需求。 分页存储过程的核心思想是利用`OFFSET`和`FETCH NEXT`这两个SQL Server 2012及更...

    通用分页存储过程(支持多表)

    通用分页存储过程主要通过接受多个参数来动态生成SQL语句,以实现对多表数据的分页查询。其核心在于灵活处理不同场景下的分页需求,包括字段选择、表连接、排序方式和额外的过滤条件等。此过程不仅简化了前端应用的...

    通用的分页存储过程,内置的函数、内连接、左外连接

    "通用的分页存储过程"是指设计一个能够适用于多种场景的存储过程,用于查询数据时实现分页显示。在大数据量的表中,分页查询是必要的,以避免一次性加载过多数据导致性能下降和用户体验不佳。 分页查询通常涉及到两...

    通用的分页存储过程

    一个最给力的分页存储过程,在程序中我们都需要对数据进行分页显示

    Oracle通用分页存储过程

    总之,"Oracle通用分页存储过程"是数据库管理和开发中的一个重要工具,它能帮助我们有效地处理大规模数据的查询,提供流畅的用户界面,并优化数据库资源的使用。通过学习和理解分页存储过程的工作原理和优化技巧,...

    SQL通用分页存储过程

    "SQL通用分页存储过程"就是一种专门用于实现分页查询的存储过程,它可以接收用户输入的参数,灵活地返回指定页码的数据。 首先,我们需要理解分页的基本概念。在数据库查询中,如果一次性获取所有数据可能导致内存...

    oracle和mssql分页存储过程-均通用

    综上所述,这个"oracle和mssql分页存储过程-均通用"的压缩包文件提供了一个跨平台的解决方案,帮助开发者在Oracle和MSSQL数据库中轻松实现高效的分页查询,同时提高了代码的可维护性和复用性。在实际应用中,应结合...

    分页 分页存储 存储过程 存储分页

    分页存储过程是指在数据库管理系统(DBMS)中使用的一种存储程序,用于高效地处理大量数据的分页查询。这种存储过程通常被设计为通用的,可以适用于不同的数据表和查询需求。存储过程是一组预先编译的SQL语句,它...

    Oracle数据库通用的分页存储过程

    本主题将详细介绍Oracle数据库中的分页存储过程及其应用场景。 分页查询允许用户逐页浏览结果集,而不是一次性加载所有数据,这对大数据量的查询尤其重要,可以有效减少内存占用并提升页面加载速度。Oracle数据库中...

    一个通用的数据分页的存储过程

    一个通用的数据分页的存储过程

Global site tag (gtag.js) - Google Analytics