SQLServer用存储过程实现分页
2007-09-21 08:32
260 查看
实现数据分页查询的方案相当多,前台和后台都有很多好方法,这些好方法都有一个共同的特点:在实现分页的同时,考虑了网络资源的占有问题。本文要讨论的是使用SQL Server存储过程的实现方法。
引子
在含有ID主键(且ID连续)的Tab表中,查找第51行到第100行数据,对应的SQL语句为:
SLECET*FROME tab WHERE ID BETWEEN 51 AND 100
如果ID不连续,或者主键为其他,则可以用下SQL语句实现同样的功能:
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif)
SELECT TOP 50 * FROM tab WHERE ID NOT IN (SELECT TOP 50 ID FROM tab)
或是
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif)
SELECT TOP 50 * FROM tab WHERE ID>@lastpage_endidi
如果用变量参数控制输入行,则使用以下语句:
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif)
SET ROWCOUNT@pagesize
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif)
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif)
SELECT * FROM tab WHERE ID>@lastpage_endid
问题
对于没有主键的表,可能存在大量重复的记录,很多SQL Server使用者喜欢用下面的语句:
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif)
SELECT IDENTITY(INT,1,1) AS ID,* INTO #T FROM tab
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif)
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif)
SELECT * FROM #T WHERE ID BETWEEN 51 AND 100
上面的方法非常笨拙,而且相当耗资源。
分析
对于这种没有主键的表,要实现分页查询,笔者认为最好的方法是加一个IDENTITY属性的主键,然后使用文本开头使用的两种方法,效率要高得多。在原表中加入IDENTITY属性的语句如下:
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif)
ALTER TABLE tab ADD ID INT IDENTITY PRIMARY KEY
并不是所有用户都有修改表的权限,下面介绍一种通用的方法:使用SQL Server 提供的储存过程sp_cursoropen。具体用法如下:
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif)
exec sp_cursoropen @P1 output,@sqlstr
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif)
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif)
exec sp_cursorfetch @P1,16,@begincol,@pagesize
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif)
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif)
exec sp_cursorclose @P1
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif)
其中第一句的@P1为生成的游标ID,@sqlstr为定义游标的SLELECT字符串;第二句中@begincol为起始行数,@pagesize为输出行数;第三句sp_cursorclose意即关闭游标。
解决
以下是笔者编写的储存过程,通过传入表名,分页取出第N页数据。
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif)
Create proc getpage
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif)
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif)
(@tablename varchar (255), @page count int=1,@pagesize int=99999999)--@tablename为表名
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif)
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif)
as
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif)
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif)
begin
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif)
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif)
set nocount on
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif)
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif)
declare @P1 int
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif)
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif)
declare @sqlstr nvarchar(400)
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif)
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif)
set @pagecount =(@pagecount-1)*@pagecount+1
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif)
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif)
set @sqlstr=’select * from ’+@tablename
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif)
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif)
exec sp_cursoropen @P1 output,@sqlstr
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif)
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif)
exec sp_cursorfetch @P1,16,@pagecount,@pagesize
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif)
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif)
exec sp_cursorclose @P1
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif)
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif)
end
调用方法
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif)
exec getpage’tab’,10,100
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif)
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif)
--表名tab ,第10页,每页100行。
进阶
以上存储过程比较通用,不过如果适当修改一下,把@sqlstr当作转入参数,就更灵活了,实现方法如下:
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif)
Create proc getpage
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif)
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif)
(@sqlstr nvarchar (4000),@pagecont int=1,@pagesize int=99999999)
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif)
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif)
as
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif)
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif)
begin
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif)
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif)
set nocount on
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif)
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif)
declare @P1 int
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif)
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif)
set @pagecount =(@pagecount-1)*@pagecount+1
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif)
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif)
exec sp_cursoropen @P1 output,@sqlstr
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif)
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif)
exec sp_cursorfetch @P1,16,@pagecount,@pagesize
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif)
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif)
exec sp_cursorclose @P1
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif)
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif)
end
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif)
调用方法:
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif)
exec getpage’SELECT * FROM tab WHERE条件 ’,10,100
引子
在含有ID主键(且ID连续)的Tab表中,查找第51行到第100行数据,对应的SQL语句为:
SLECET*FROME tab WHERE ID BETWEEN 51 AND 100
如果ID不连续,或者主键为其他,则可以用下SQL语句实现同样的功能:
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif)
SELECT TOP 50 * FROM tab WHERE ID NOT IN (SELECT TOP 50 ID FROM tab)
或是
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif)
SELECT TOP 50 * FROM tab WHERE ID>@lastpage_endidi
如果用变量参数控制输入行,则使用以下语句:
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif)
SET ROWCOUNT@pagesize
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif)
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif)
SELECT * FROM tab WHERE ID>@lastpage_endid
问题
对于没有主键的表,可能存在大量重复的记录,很多SQL Server使用者喜欢用下面的语句:
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif)
SELECT IDENTITY(INT,1,1) AS ID,* INTO #T FROM tab
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif)
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif)
SELECT * FROM #T WHERE ID BETWEEN 51 AND 100
上面的方法非常笨拙,而且相当耗资源。
分析
对于这种没有主键的表,要实现分页查询,笔者认为最好的方法是加一个IDENTITY属性的主键,然后使用文本开头使用的两种方法,效率要高得多。在原表中加入IDENTITY属性的语句如下:
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif)
ALTER TABLE tab ADD ID INT IDENTITY PRIMARY KEY
并不是所有用户都有修改表的权限,下面介绍一种通用的方法:使用SQL Server 提供的储存过程sp_cursoropen。具体用法如下:
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif)
exec sp_cursoropen @P1 output,@sqlstr
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif)
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif)
exec sp_cursorfetch @P1,16,@begincol,@pagesize
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif)
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif)
exec sp_cursorclose @P1
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif)
其中第一句的@P1为生成的游标ID,@sqlstr为定义游标的SLELECT字符串;第二句中@begincol为起始行数,@pagesize为输出行数;第三句sp_cursorclose意即关闭游标。
解决
以下是笔者编写的储存过程,通过传入表名,分页取出第N页数据。
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif)
Create proc getpage
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif)
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif)
(@tablename varchar (255), @page count int=1,@pagesize int=99999999)--@tablename为表名
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif)
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif)
as
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif)
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif)
begin
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif)
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif)
set nocount on
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif)
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif)
declare @P1 int
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif)
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif)
declare @sqlstr nvarchar(400)
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif)
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif)
set @pagecount =(@pagecount-1)*@pagecount+1
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif)
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif)
set @sqlstr=’select * from ’+@tablename
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif)
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif)
exec sp_cursoropen @P1 output,@sqlstr
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif)
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif)
exec sp_cursorfetch @P1,16,@pagecount,@pagesize
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif)
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif)
exec sp_cursorclose @P1
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif)
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif)
end
调用方法
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif)
exec getpage’tab’,10,100
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif)
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif)
--表名tab ,第10页,每页100行。
进阶
以上存储过程比较通用,不过如果适当修改一下,把@sqlstr当作转入参数,就更灵活了,实现方法如下:
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif)
Create proc getpage
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif)
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif)
(@sqlstr nvarchar (4000),@pagecont int=1,@pagesize int=99999999)
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif)
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif)
as
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif)
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif)
begin
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif)
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif)
set nocount on
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif)
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif)
declare @P1 int
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif)
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif)
set @pagecount =(@pagecount-1)*@pagecount+1
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif)
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif)
exec sp_cursoropen @P1 output,@sqlstr
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif)
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif)
exec sp_cursorfetch @P1,16,@pagecount,@pagesize
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif)
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif)
exec sp_cursorclose @P1
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif)
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif)
end
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif)
调用方法:
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif)
exec getpage’SELECT * FROM tab WHERE条件 ’,10,100
相关文章推荐
- SQLServer用存储过程实现分页
- sqlserver存储过程实现多表分页
- SQLSERVER 存储过程实现分页查询 C#后台获取查询结果集
- PostgGresql如何简单实现sqlserver中的分页存储过程
- 调用存储过程实现分页(二)
- 玩转Web之Jsp(三)-----Jsp+SQLServer 用sql语句实现分页
- JAVA调用MYSQL存储过程实现分页
- 用存储过程实现的分页程序
- SQL Server2000 索引结构及其使用 (实现小数据量和海量数据的通用分页显示存储过程)
- Oracle 存储过程-实现分页 + 代码案例
- 实现海量数据和小数据量的通用分页显示存储过程
- Oracle、MySQL、SQLServer实现分页
- 存储过程实现分页 (载至网上) ——~——
- 使用系统存储过程实现的通用分页存储过程
- JDBC调用mysql存储过程实现分页效果
- oracle mysql SqlServer 数据库分页实现sql
- java 调用存储过程实现分页 sql server 2012 版
- 利用SqlServer内部存储过程实现快速方便的分页
- Oracle之存储过程实现分页
- 用存储过程实现的分页程序