实现千万级数据的分页通用存储过程

set ANSI_NULLS ON
set QUOTED_IDENTIFIER ON
go

/* 
功能描述: 通用分页显示查询 
如果有自增标识字段,在@strGetFields中不要加入此字段信息, 
如果非要加入的话,要 (fldName + 0) AS fldName 这样处理; 
输入参数: 
@tblName: 表名 
@strGetFields: 需要返回的列 '*':返回所以列信息 
@PageSize: 页尺寸 
@PageIndex: 页码 
@doCount: 返回记录总数, 非 0 值则返回 
@strOrderBy: 排序字段信息,(注意: 不要加 ORDER BY) 
格式: Field1 DESC, Field2 ASC 
@strWhere: 查询条件,(注意: 不要加 WHERE) 
输出参数: @RecordCount: 记录总数 
作 者: Nestcn 
创建时间: 2010-03-09 
更改纪录: 
*/ 
ALTER PROCEDURE [dbo].[MyPagination] 
( 
@tblName varchar(255), 
@strGetFields varchar(1000) = '*', 
@PageSize int = 10, 
@PageIndex int = 1, 
@doCount bit = 0, 
@strOrderBy varchar(500) = '', 
@strWhere varchar(1500) = '', 
@RecordCount int output 
) 
AS 
-- 主语句 
DECLARE @strSQL varchar(5000) SET @strSQL = '' 
-- 排序变量 
DECLARE @strOrder varchar(400) SET @strOrder = '' 

SET @RecordCount = 0 
--如果@doCount传递过来的不是0,就执行总数统计 
IF (@doCount != 0) 
BEGIN 
DECLARE @sWhere varchar(2000) 

SET @sWhere = '' 
IF (@strWhere != '') 
SET @sWhere = ' WHERE ' + @strWhere 

SET @strSQL = 'if exists (select * from dbo.sysobjects where id = object_id(''[dbo].[tmpTable]'') and OBJECTPROPERTY(id, ''IsUserTable'') = 1) ' 
SET @strSQL = @strSQL + ' UPDATE tmpTable SET Total = (SELECT COUNT(*) FROM [' + @tblName + '] ' + @sWhere + ') ' 
SET @strSQL = @strSQL + ' ELSE SELECT COUNT(*) AS Total INTO tmpTable FROM [' + @tblName + '] ' + @sWhere 

EXEC (@strSQL) 

SELECT @RecordCount=Total FROM tmpTable 

--删除总数统计临时表 
EXEC ('DROP TABLE tmpTable') 
END 

PRINT @RecordCount 

--排序字段信息 
IF (@strOrderBy != '') 
SET @strOrder = ' ORDER BY ' + @strOrderBy 
--如果是第一页就执行以上代码,这样会加快执行速度 
IF (@PageIndex = 1) 
BEGIN 
IF (@strWhere != '') 
SET @strSQL = 'SELECT TOP ' + str(@PageSize) + ' ' + @strGetFields + ' FROM [' + @tblName + '] WHERE ' + @strWhere + @strOrder 
ELSE 
SET @strSQL = 'SELECT TOP ' + str(@PageSize) + ' ' + @strGetFields + ' FROM ['+ @tblName + '] '+ @strOrder 
END 
ELSE 
BEGIN 
--为搜索表建立自动编号 保存到临时表中 
SET @strSQL = 'SELECT TOP ' + str(@PageIndex*@PageSize) + ' IDENTITY(int,1,1) AS IID, ' + @strGetFields + ' INTO #tmpTable FROM [' + @tblName + ']' 
IF (@strWhere != '') 
SET @strSQL = @strSQL + ' WHERE ' + @strWhere + @strOrder 
ELSE 
SET @strSQL = @strSQL + @strOrder 

--以下代码赋予了@strSQL以真正执行的SQL代码 
SET @strSQL = @strSQL + ' SELECT ' + @strGetFields + ' FROM #tmpTable WHERE IID > ' + str((@PageIndex-1)*@PageSize) + ' DROP TABLE #tmpTable' 
END 

PRINT @strSQL 

--执行分页查询 
EXEC (@strSQL) 

posted @ 2010-03-09 12:46  Tao310  阅读(...)  评论(... 编辑 收藏