http://www.cnblogs.com/edobnet/archive/2008/01/23/1049985.html
存储过程代码如下:
ALTER PROCEDURE [dbo].[Pg_Paging]
@Tables varchar(1000), --表名,多红表是请使用 tA a inner join tB b On a.AID = b.AID
@PK varchar(100), --主键,可以带表头 a.AID
@Sort varchar(200) = '', --排序字段
@PageNumber int = 1, --开始页码
@PageSize int = 10, --页大小
@Fields varchar(1000) = '*',--读取字段
@Filter varchar(1000) = NULL,--Where条件
@Group varchar(1000) = NULL, --分组
@isCount bit = 0 --1 --是否获得总记录数
AS
--
--select * from GL_NEWS order by GN_UPDATE_DATE DESC
--exec Pg_Paging @Tables = 'tb_NewsInfo', @PK = 'News_ID', @Sort = 'News_ID DESC', @PageNumber = 2, @PageSize = 15,@Fields = '*', @Group = '', @isCount = 0
DECLARE @strFilter varchar(2000)
declare @sql varchar(8000)
IF @Filter IS NOT NULL AND @Filter != ''
BEGIN
SET @strFilter = ' WHERE ' + @Filter + ' '
END
ELSE
BEGIN
SET @strFilter = ''
END
if @isCount = 1 --只获得记录条数
begin
set @sql = 'SELECT Count(*) FROM ' + @Tables + @strFilter
end
else
begin
if @Sort = ''
set @Sort = @PK + ' DESC '
IF @PageNumber < 1
SET @PageNumber = 1
if @PageNumber = 1 --第一页提高性能
begin
set @sql = 'select top ' + str(@PageSize) +' '+@Fields+ ' from ' + @Tables + ' ' + @strFilter + ' ORDER BY '+ @Sort
end
else
begin
/*Execute dynamic query*/
DECLARE @START_ID varchar(50)
DECLARE @END_ID varchar(50)
SET @START_ID = convert(varchar(50),(@PageNumber - 1) * @PageSize + 1)
SET @END_ID = convert(varchar(50),@PageNumber * @PageSize)
set @sql = ' SELECT '+@Fields+ '
FROM (SELECT ROW_NUMBER() OVER(ORDER BY '+@Sort+') AS rownum,
'+@Fields+ '
FROM ' ' +@strFilter++@Tables+'') AS D
WHERE rownum BETWEEN '+@START_ID+' AND ' +@END_ID +' ORDER BY '+@Sort
END
END
--print @sql
EXEC(@sql)
GO
/****** 对象: StoredProcedure [dbo].[UP_GetRecordByPage] 脚本日期: 01/23/2008 16:28:31 ******/
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
ALTER PROCEDURE [dbo].[UP_GetRecordByPage]
@tblName varchar(255), -- 表名
@fldName varchar(255), -- 主键或者排序字段名
@PageSize int = 10, -- 页尺寸
@PageIndex int = 1, -- 页码
@IsReCount bit = 0, -- 返回记录总数, 非 0 值则返回
@OrderType bit = 0, -- 设置排序类型, 非 0 值则降序
@strWhere varchar(1000) = '', -- 查询条件 (注意: 不要加 where)
@strSelectField varchar(500) --查询的列(所有列是*,其他是code,name,type)
AS
declare @strSQL varchar(6000) -- 主语句
declare @strTotal varchar(2000) -- 获取记录数合计语句
declare @strTmp varchar(1000) -- 临时变量
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)+ ' ' + @strSelectField + ' 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)+ ' ' + @strSelectField + ' 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)+ ' ' + @strSelectField + ' from ['
+ @tblName + ']' + @strTmp + ' ' + @strOrder
end
if @strWhere != ''
set @strTotal = 'select count(*) as Total from [' + @tblName + ']'+' where ' + @strWhere
else
set @strTotal = 'select count(*) as Total from [' + @tblName + ']'
exec (@strSQL)
if @IsReCount != 0
exec (@strTotal)
完全可以避免返回多余的字段的问题。
1、可以自定义要返回的字段,避免查询多余的字段数据
2、可以执行一次,同时返回相应页面的数据和查询表的所有记录总数
3、可以适应有主键和没主键的表,可以根据非主键字段进行排序,不过,需要将该字段加上索引,性能有一定的损失。
4、适应3000万以下的数据行,1000万以下的数据查询1s之内返回,3000万的数据大约需要3s。需要看返回的字段和表是否有主键
01 | USE [DATA_TEMP] |
02 | GO |
03 | /****** 对象: StoredProcedure [dbo].[im531_Page] 脚本日期: 11/26/2010 10:52:35 ******/ |
04 | SET ANSI_NULLS ON |
05 | GO |
06 | SET QUOTED_IDENTIFIER ON |
07 | GO |
08 | |
09 | -- ============================================= |
10 | -- Author: im531 |
11 | -- Create date: 2010-10-25 |
12 | -- Description: SQL 2005 ROW_NUMBER 分页 |
13 | -- Modify Date: 2010-10-26 |
14 | -- ============================================= |
15 | |
16 | CREATE PROCEDURE [dbo].[im531_Page] |
17 | @TabeName AS NVARCHAR(50), |
18 | @Fields AS NVARCHAR(1024), |
19 | @SearchWhere AS NVARCHAR(1024), |
20 | @OrderFields AS NVARCHAR(1024), |
21 | @pageNumber AS INT , |
22 | @page AS INT |
23 | AS |
24 | BEGIN |
25 | SET NOCOUNT ON ; |
26 | DECLARE @sqlType AS TINYINT |
27 | SET @sqlType = 0 -- 0 BETWEEN 1 TOP |
28 | DECLARE @sql AS NVARCHAR( MAX ) |
29 | IF @SearchWhere <> '' SET @SearchWhere = ' WHERE ' + @SearchWhere |
30 | IF @page < 2 SET @page = 1 |
31 | IF @page = 1 |
32 | BEGIN |
33 | SET @sql = 'SELECT TOP ' + CONVERT (NVARCHAR(20),@pageNumber) + ' ' + @Fields |
34 | + 'FROM [' + @TabeName + '][a] WITH(NOLOCK) ' + @SearchWhere + ' ORDER BY ' + @OrderFields |
35 | END |
36 | ELSE |
37 | BEGIN |
38 | --临时表 |
39 | SET @sql = ';WITH [Page_____Table] AS(' |
40 | + 'SELECT ROW_NUMBER() OVER(ORDER BY ' + @OrderFields + ') AS [RowNow],' + @Fields |
41 | + 'FROM [' + @TabeName + ' ][a] WITH(NOLOCK) ' + @SearchWhere |
42 | + ')' |
43 | --查找当前页面记录 |
44 | IF @sqlType = 0 |
45 | BEGIN |
46 | -- A USE BETWEEN |
47 | SET @sql = @sql + 'SELECT *' |
48 | + 'FROM [Page_____Table] WITH(NOLOCK)' |
49 | + 'WHERE [RowNow] BETWEEN ' + CONVERT (NVARCHAR(20),(@page - 1) * @pageNumber + 1) + ' AND ' + CONVERT (NVARCHAR(20),@page * @pageNumber) |
50 | + 'ORDER BY [RowNow]' |
51 | END |
52 | ELSE |
53 | BEGIN |
54 | -- B USE TOP |
55 | SET @sql = @sql + 'SELECT TOP ' + CONVERT (NVARCHAR(20),@pageNumber) + ' *' |
56 | + 'FROM [Page_____Table] WITH(NOLOCK)' |
57 | + 'WHERE [RowNow] > ' + CONVERT (NVARCHAR(20),(@page - 1) * @pageNumber) |
58 | + 'ORDER BY [RowNow]' |
59 | END |
60 | END |
61 | EXEC (@sql) |
62 | END |