目前基于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数据库的存储过程,主要用于实现高效的分页查询功能...
MySQL存储过程是数据库管理系统中的一种重要功能,它允许开发者编写一系列复杂的SQL语句,...同时,结合标签“源码”和“工具”,可能还涉及到如何将这些存储过程集成到开发工具或脚本中,以自动化处理数据分页的工作。
web中通用分页存储过程,是根据PageIndex来取得相应的页数据,并不是上下翻页,对单字段,多字段均适用,并在百万级数据上测试,分页速度较好。
万能分页存储过程之所以被称为“万能”,是因为它应该具备足够的灵活性和通用性,能够适应各种表结构和查询需求,而不局限于特定的场景或数据模型。 首先,我们来理解分页的基本原理。分页查询通常涉及到两个关键...
### 几款通用的SQL分页存储过程:深入解析与应用 在数据库操作中,分页查询是一项常见的需求,尤其当数据量庞大时,合理的分页可以极大地提高查询效率和用户体验。本文将深入分析两款通用的SQL分页存储过程,分别...
标题提到的“通用的SQL server分页存储过程”提供了一种解决方案,可以避免重复编写存储过程,只需调整参数即可满足不同分页需求。 分页存储过程的核心思想是利用`OFFSET`和`FETCH NEXT`这两个SQL Server 2012及更...
通用分页存储过程主要通过接受多个参数来动态生成SQL语句,以实现对多表数据的分页查询。其核心在于灵活处理不同场景下的分页需求,包括字段选择、表连接、排序方式和额外的过滤条件等。此过程不仅简化了前端应用的...
"通用的分页存储过程"是指设计一个能够适用于多种场景的存储过程,用于查询数据时实现分页显示。在大数据量的表中,分页查询是必要的,以避免一次性加载过多数据导致性能下降和用户体验不佳。 分页查询通常涉及到两...
一个最给力的分页存储过程,在程序中我们都需要对数据进行分页显示
总之,"Oracle通用分页存储过程"是数据库管理和开发中的一个重要工具,它能帮助我们有效地处理大规模数据的查询,提供流畅的用户界面,并优化数据库资源的使用。通过学习和理解分页存储过程的工作原理和优化技巧,...
"SQL通用分页存储过程"就是一种专门用于实现分页查询的存储过程,它可以接收用户输入的参数,灵活地返回指定页码的数据。 首先,我们需要理解分页的基本概念。在数据库查询中,如果一次性获取所有数据可能导致内存...
综上所述,这个"oracle和mssql分页存储过程-均通用"的压缩包文件提供了一个跨平台的解决方案,帮助开发者在Oracle和MSSQL数据库中轻松实现高效的分页查询,同时提高了代码的可维护性和复用性。在实际应用中,应结合...
分页存储过程是指在数据库管理系统(DBMS)中使用的一种存储程序,用于高效地处理大量数据的分页查询。这种存储过程通常被设计为通用的,可以适用于不同的数据表和查询需求。存储过程是一组预先编译的SQL语句,它...
本主题将详细介绍Oracle数据库中的分页存储过程及其应用场景。 分页查询允许用户逐页浏览结果集,而不是一次性加载所有数据,这对大数据量的查询尤其重要,可以有效减少内存占用并提升页面加载速度。Oracle数据库中...
一个通用的数据分页的存储过程