[百万级]通用存储过程.分页存储过程.
/*
?名称:spAll_ReturnRows
?输入:
?输出:
?调用:
??EXEC spAll_ReturnRows 'SELECT? * FROM 表名', 页号, 返回记录数, '主键', '排序字段'
??spAll_ReturnRows 'SELECT? * FROM all_Categories',2,10,'[ID]','[ID]'
?说明:[百万级]通用存储过程.分页存储过程..返回指定返回条数、指定页数的记录
?作者:Dili J.F. Senders
? 邮件:diliatwellknow.net
? 网站:http://12986.com
? 更新:20040610
? 支持:http://cs.12986.com
? 版权:转述时请注明来源
*/
CREATE PROCEDURE dbo.spAll_ReturnRows
(
?@SQL nVARCHAR(4000),
?@Page int,
?@RecsPerPage int,
?@ID VARCHAR(255),
?@Sort VARCHAR(255)
)
AS
DECLARE @Str nVARCHAR(4000)
SET @Str='SELECT?? TOP '+CAST(@RecsPerPage AS VARCHAR(20))+' * FROM ('+@SQL+') T WHERE T.'+@ID+' NOT IN
(SELECT?? TOP '+CAST((@RecsPerPage*(@Page-1)) AS VARCHAR(20))+' '+@ID+' FROM ('+@SQL+') T9 ORDER BY '+@Sort+') ORDER BY '+@Sort
PRINT @Str
EXEC sp_ExecuteSql @Str
GO
-------------------------------------------------------------------------------------------------------
实现千万级数据的分页显示!
/*
名称:spAll_DeleteNoneUnique
输入:要查询的表名和字段列表
输出:
调用:
说明:实现千万级数据的分页显示!--可以在5秒内获取1448万条记录里的第1200页的100条记录,雄不?
作者:铁拳
邮件:
网站:http://www.wellknow.net
更新:20040610
支持:http://bbs.wellknow.net
版权:转述时请注明来源:用思维创造未来的Wellknow.net
*/
CREATE PROCEDURE GetRecordFromPage
@tblName varchar(255), -- 表名
@fldName varchar(255), -- 字段名
@PageSize int = 10, -- 页尺寸
@PageIndex int = 1, -- 页码
@IsCount bit = 0, -- 返回记录总数, 非 0 值则返回
@OrderType bit = 0, -- 设置排序类型, 非 0 值则降序
@strWhere varchar(1000) = '' -- 查询条件 (注意: 不要加 where)
AS
declare @strSQL varchar(6000) -- 主语句
declare @strTmp varchar(100) -- 临时变量
declare @strOrder varchar(400) -- 排序类型
if @OrderType != 0
begin
set @strTmp = "<(select min"
set @strOrder = " order by [" + @fldName +"] desc"
end
else
begin
set @strTmp = ">(select max"
set @strOrder = " order by [" + @fldName +"] asc"
end
set @strSQL = "select top " + str(@PageSize) + " * from ["
+ @tblName + "] where [" + @fldName + "]" + @strTmp + "(["
+ @fldName + "]) from (select top " + str((@PageIndex-1)*@PageSize) + " ["
+ @fldName + "] from [" + @tblName + "]" + @strOrder + ") as tblTmp)"
+ @strOrder
if @strWhere != ''
set @strSQL = "select top " + str(@PageSize) + " * from ["
+ @tblName + "] where [" + @fldName + "]" + @strTmp + "(["
+ @fldName + "]) from (select top " + str((@PageIndex-1)*@PageSize) + " ["
+ @fldName + "] from [" + @tblName + "] where " + @strWhere + " "
+ @strOrder + ") as tblTmp) and " + @strWhere + " " + @strOrder
if @PageIndex = 1
begin
set @strTmp = ""
if @strWhere != ''
set @strTmp = " where " + @strWhere
set @strSQL = "select top " + str(@PageSize) + " * from ["
+ @tblName + "]" + @strTmp + " " + @strOrder
end
if @IsCount != 0
set @strSQL = "select count(*) as Total from [" + @tblName + "]"
exec (@strSQL)
GO
--------------------------------------------------------------------------------------------------------
1。我个人认为最好的分页方法是:
![](https://www.cnblogs.com/Images/OutliningIndicators/None.gif)
写成存储过程,上面的语句要拼一下sql语句,要获得最后大于的哪一个ID号
2。那个用游标的方式,只适合于小数据量的表,如果表在一万行以上,就差劲了
你的存储过程还比不上NOT IN分页,示例:
![](https://www.cnblogs.com/Images/OutliningIndicators/None.gif)
![](https://www.cnblogs.com/Images/OutliningIndicators/None.gif)
![](https://www.cnblogs.com/Images/OutliningIndicators/None.gif)
![](https://www.cnblogs.com/Images/OutliningIndicators/None.gif)
3。以下是我用存储过程分页的方式,分页一个20万行的表,结果显示在网页中,你可以看一下速度:
http://www.bizlands.com/trade/search.asp?type=s&sortid=15
4。很久前,我说过用sql的游标
游标是存放在内存中,很费内存.
游标一建立,就将相关的记录锁住,直到取消游标
游标提供了对特定集合中逐行扫描的手段,一般使用游标来逐行遍历数据,根据取出数据条件的不同进行不同的操作。而对于多表和大表中定义的游标(大的数据集合)循环很容易使程序进入一个漫长的等待甚至死机.
所以说,我个人的经验,就是一万上行上的表,不用游标.小数据量的表,适当的时候可以用游标
因为游标,遍历小数据量的行集还是不错的一个方法!
5。用临时表自定义分页和使用游标自定义分页都不好!
---------------------------------SqlServer内部的分页功能-----------------------------------------------------
1)只需要提供Sql语句和每页的记录数,页数就可以了
2)速度超快哟,100W记录1~3秒就分出来了
3)对于存储过程特别好用
--//调用的方式
表
exec up_zbh_DivPageBySql 'select * from 表',10,3
存储过程
exec up_zbh_DivPageBySql 'exec 存储过程',10,1
--//我吧它封装成一个存储过程,调用的时候方便的很哈!!
create procedure up_zbh_DivPageBySql
@strSql varchar(8000),
@nPageSize int,
@nPageCount int
as
SET NOCOUNT ON
DECLARE @P1 INT,
@nRowCount INT
--//注意:@scrollopt = 1 会取得Select的时候的总行数
EXEC sp_cursoropen @P1 OUTPUT, @strSql, @scrollopt = 2, @ccopt = 335873, @rowcount = @nRowCount OUTPUT
IF (@P1 != 0)
BEGIN
--SELECT @nRowCount AS nRecordCount, ceiling(1.0 * @nRowCount / @nPageSize) AS nPageCount, @nPageCount AS nPage
SET @nPageCount = (@nPageCount - 1) * @nPageSize + 1
EXEC sp_cursorfetch @P1, 32, @nPageCount, @nPageSize
EXEC sp_cursorclose @P1
END
GO
--//调用的方式
表
exec up_zbh_DivPageBySql 'select * from 表',10,3
存储过程
exec up_zbh_DivPageBySql 'exec 存储过程',10,1