真正通用的SQL分页存储过程
关于SQL分页的问题,网上找到的一些SQL其实不能真正做到通用,他们主要是以自增长ID做为前提的。但在实际使用中,很多表不是自增长的,而且主键也不止一个字段,其实我们稍做改进就可以达到通用。这里还增加了索引,以方便大数据量的使用(代码中是先抓到临时表的,从性能上说如果采用自增长式的ID表,当然可以不使用临时表以达到性能的提升)。以下代码的SP是经过我们项目使用通过的。因朋友问及此问题,我就放在这里供大家分享,如各位大侠有更好的方法,也请告诉我。在这里先感谢各位了。
ALTER PROCEDURE [dbo].[SP_PageResult2]
-- 获得某一页的数据 --
@currPage int = 1, --当前页页码 (即Top currPage)
@showColumn varchar(2000) = '*', --需要得到的字段 (即 column1,column2,......)
@tabName varchar(2000), --需要查看的表名 (即 from table_name)
@strCondition varchar(2000) = '', --查询条件 (即 where condition......) 不用加where关键字
@ascColumn varchar(100) = '', --排序的字段名 (即 order by column asc/desc)
@bitOrderType bit = 0, --排序的类型 (0为升序,1为降序)
--@pkColumn varchar(50) = '', --主键名称
@pageSize int = 20 --分页大小
-- SP_PageResult2 '1','*','Bom','1=1','Ancestor',0,30
AS
BEGIN -- 存储过程开始
-- 该存储过程需要用到的几个变量 --
DECLARE @strTemp varchar(1000)
DECLARE @strSql varchar(4000) --该存储过程最后执行的语句
DECLARE @strOrderType varchar(1000) --排序类型语句 (order by column asc或者order by column desc)
DECLARE @RIDorder varchar(100)
BEGIN
IF @bitOrderType = 1 -- bitOrderType=1即执行降序
BEGIN
SET @strOrderType = ' ORDER BY '+@ascColumn+' DESC'
SET @strTemp = '>(SELECT max' -- 因为降降得升,所以这里依然是>(SELECT max ,而不是<(SELECT min
SET @RIDorder = ' ORDER BY RID ASC' -- 因为降降得升。所以这里依然是asc
END
ELSE
BEGIN
SET @strOrderType = ' ORDER BY '+@ascColumn+' ASC'
SET @strTemp = '>(SELECT max'
SET @RIDorder = ' ORDER BY RID ASC'
END IF @currPage = 1 -- 如果是第一页
BEGIN
IF @strCondition != ''
BEGIN
SET @strSql = 'SELECT row_number() over (' + @strOrderType +') AS RID,'+@showColumn+' INTO #T FROM '+@tabName+ ' WHERE '+@strCondition+' '+@strOrderType +'; create index I1 on #T(RID);'
SET @strSql = @strSql + ' SELECT TOP '+STR(@pageSize)+@showColumn+' FROM #T ' + @RIDorder END
ELSE
BEGIN
SET @strSql = 'SELECT row_number() over (' + @strOrderType +') AS RID,'+@showColumn+' INTO #T FROM '+@tabName+ ' '+@strOrderType +'; create index I1 on #T(RID);'
SET @strSql = @strSql + ' SELECT TOP '+STR(@pageSize)+@showColumn+' FROM #T ' + @RIDorder END
END ELSE -- 其他页
BEGIN IF @strCondition !=''
BEGIN
SET @strSql = 'SELECT row_number() over (' + @strOrderType +') AS RID,'+@showColumn+' INTO #T FROM '+@tabName+ ' WHERE '+@strCondition+' '+@strOrderType +'; create index I1 on #T(RID);'
SET @strSql = @strSql + 'SELECT TOP '+STR(@pageSize)+' '+@showColumn+' FROM '+'#T'+
' WHERE '+@strCondition+' AND '+'RID'+@strTemp+'('+'RID'+')'+' FROM (SELECT TOP '+STR((@currPage-1)*@pageSize)+
' '+'RID'+' FROM '+'#T'+@RIDorder+') AS TabTemp)'+@RIDorder
END
ELSE
BEGIN
SET @strSql = 'SELECT row_number() over (' + @strOrderType +') AS RID,'+@showColumn+' INTO #T FROM '+@tabName+' ' + @strOrderType +'; create index I1 on #T(RID);'
SET @strSql = @strSql + 'SELECT TOP '+STR(@pageSize)+' '+@showColumn+' FROM '+'#T'+
' WHERE '+'RID'+@strTemp+'('+'RID'+')'+' FROM (SELECT TOP '+STR((@currPage-1)*@pageSize)+' '+'RID'+
' FROM '+'#T'+@RIDorder+') AS TabTemp)'+@RIDorder
END
END END
--IF @strCondition != ''
-- set @strSql=@strSql+';select count(*) from '+ @tabName +' where '+ @strCondition +';DROP TABLE #T'
--else
set @strSql=@strSql+';select count(*) from '+ '#T' + ';DROP TABLE #T'
print @strSql
exec (@strSql) END -- 存储过程结束
下图为调用结果,从结果来看。正确的。
真正通用的SQL分页存储过程的更多相关文章
- [转]关于SQL分页存储过程的分析
[转]关于SQL分页存储过程的分析 建立一个 Web 应用,分页浏览功能必不可少.这个问题是数据库处理中十分常见的问题.经典的数据分页方法是:ADO 纪录集分页法,也就是利用ADO自带的分页功能(利用 ...
- Delphi调用SQL分页存储过程实例
Delphi调用SQL分页存储过程实例 (-- ::)转载▼ 标签: it 分类: Delphi相关 //-----下面是一个支持任意表的 SQL SERVER2000分页存储过程 //----分页存 ...
- 完整SQL分页存储过程(支持多表联接)
http://www.cnblogs.com/andiki/archive/2009/03/24/1420289.html Code/********************************* ...
- 关于SQL分页存储过程的分析
建 立一个 Web 应用,分页浏览功能必不可少.这个问题是数据库处理中十分常见的问题.经典的数据分页方法是:ADO 纪录集分页法,也就是利用ADO自带的分页功能(利用游标)来实现分页.但这种分页方法仅 ...
- SQL - 分页存储过程
http://www.jb51.net/article/71193.htm http://www.webdiyer.com/utils/spgenerator/ create PROCEDURE [d ...
- 修改后的SQL分页存储过程,利用2分法,支持排序
/****** Object: StoredProcedure [dbo].[sys_Page_v3] Script Date: 08/13/2014 09:32:28 ******/ SET ANS ...
- sql分页存储过程比较
一,先创建一百万条数据 drop table #tmp create table #tmp ( id ,) primary key, name ) ) declare @i int begin ins ...
- MS SQL 分页存储过程
最近换了家新公司,但是新公司没有使用分页的存储过程.那我就自个写一个往项目上套 (效率怎么样就不怎么清楚没有详细的测试过) CREATE PROCEDURE [dbo].[pro_common_pag ...
- sql分页存储过程,带求和、排序
创建存储过程: CREATE PROCEDURE [dbo].[sp_TBTest_Query] ( @PageSize INT, --每页多少条记录 @PageIndex INT = 1, --指定 ...
随机推荐
- mysql (master/slave)复制原理及配置
1 复制概述 Mysql内建的复制功能是构建大型,高性能应用程序的基础.将Mysql的数据分布到多个系统上去,这种分布的机制,是通过将Mysql的某一台主机的数据复制到其它主机(slaves)上,并重 ...
- 基于CentOS与VmwareStation10搭建Oracle11G RAC 64集群环境:2.搭建环境-2.4. 安装JDK
2.4.安装JDK 2.4.1.准备JDK 在百度搜索:JDK下载 2.4.2.上传JDK put E:\软件安装文件\jdk-8u11-linux-x64.rpm /home/linuxrac1/D ...
- input框内默认文字点击消失
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/ ...
- scala: How to write a simple HTTP GET request client in Scala (with a timeout)
Scala CookBook: http://scalacookbook.com/ @throws(classOf[java.io.IOException]) @throws(classOf[java ...
- (转)android中利用 ViewPage 实现滑动屏
最近实现了这样的一个效果:滑动界面出现拖拽效果,可翻动3屏,也可点击按钮翻动页面. 主要利用android.support.v4.view.ViewPager控件来实现. 第一个界面: 滑动屏幕: 换 ...
- DNN 错误代码 0x80070005 解决方案
在IIS上创建DNN站点,可能出现的错误代码:0x80070005,因为权限不足而不能访问DNN. 解决方法:打开IIS, 1.右键目标网站->编辑权限->安全->添加组或者用户 “ ...
- 在Cubieboard上关闭irqbalance服务避免内存泄漏
十一一个假期回来,顺手看了看自己的cubieboard运行状态怎么样 aria2正常: btsync正常: samba正常: 很好, 顺手htop一下,已经开机了13天了,CPU使用率4%,内存使用率 ...
- algorithm@ Sieve of Eratosthenes (素数筛选算法) & Related Problem (Return two prime numbers )
Sieve of Eratosthenes (素数筛选算法) Given a number n, print all primes smaller than or equal to n. It is ...
- 【转】webgame前台开发总结--虽然是10年的文章,但是也有参考价值
一.webgame整个游戏流程: 1.预加载(打开游戏页面后,显示进度条,主要加载前期的登陆和创建角色资源,创建角色资源的加载可以放到进入创建角色界面的时候加载,因为玩家除了第一次进入游戏,其他时间基 ...
- 通过用 .NET 生成自定义窗体设计器来定制应用程序
通过用 .NET 生成自定义窗体设计器来定制应用程序 https://www.microsoft.com/china/MSDN/library/netFramework/netframework/Cu ...