分页存储过程:
CREATE PROCEDURE [USP_Product_GetPaged] @WhereClause VARCHAR (2000), @OrderBy VARCHAR (2000), @PageIndex INT, @PageSize INT AS BEGIN DECLARE @PageLowerBound INT, @PageUpperBound INT SET @PageLowerBound = @PageSize * @PageIndex SET @PageUpperBound = @PageLowerBound + @PageSize CREATE TABLE #PageIndex ( [IndexID] INT IDENTITY (1, 1) NOT NULL, [ProductID] INT ) DECLARE @SQL AS NVARCHAR(4000) SET @SQL = 'INSERT INTO #PageIndex ([ProductID])' SET @SQL = @SQL + ' SELECT' IF @PageSize > 0 SET @SQL = @SQL + ' TOP ' + CONVERT(NVARCHAR, @PageUpperBound) SET @SQL = @SQL + ' [ProductID]' SET @SQL = @SQL + ' FROM [dbo].[Product]' IF LEN(@WhereClause) > 0 SET @SQL = @SQL + ' WHERE ' + @WhereClause IF LEN(@OrderBy) > 0 SET @SQL = @SQL + ' ORDER BY ' + @OrderBy EXEC (@SQL) SELECT TempTable.[ProductID], TempTable.[ProductCode], TempTable.[ProductName], TempTable.[CategoryID], TempTable.[UnitPrice] FROM [dbo].[Product] TempTable INNER JOIN #PageIndex PageIndex ON TempTable.[ProductID] = PageIndex.[ProductID] WHERE PageIndex.IndexID > @PageLowerBound AND PageIndex.IndexID <= @PageUpperBound ORDER BY PageIndex.IndexID SET @SQL = 'SELECT COUNT(*) AS TotalRowCount' SET @SQL = @SQL + ' FROM [dbo].[Product]' IF LEN(@WhereClause) > 0 SET @SQL = @SQL + ' WHERE ' + @WhereClause EXEC (@SQL) END GO
执行分页存储过程示例:
-- 不带Where子句 EXECUTE [USP_Product_GetPaged] '', '[ProductID] ASC', 0, 10 EXECUTE [USP_Product_GetPaged] '', '[ProductID] ASC', 1, 10 -- Where子句 EXECUTE [USP_Product_GetPaged] '[UnitPrice] > 20', '[UnitPrice] DESC', 0, 10 EXECUTE [USP_Product_GetPaged] '[UnitPrice] > 20', '[UnitPrice] DESC', 1, 10
ROW_NUMBER()函数是SQL Server 2005新增的排名函数,可以使用ROW_NUMBER()进行分页。
SELECT TOP (10) [t].[ProductID] AS [ProductID], [t].[ProductName] AS [ProductName] FROM ( SELECT [ProductID] AS [ProductID], [ProductName] AS [ProductName], ROW_NUMBER() OVER (ORDER BY [ProductID] ASC) AS [row_number] FROM [dbo].[Product] WHERE [UnitPrice] > 20 ) AS [t] WHERE [t].[row_number] > 10 ORDER BY [t].[ProductID] ASC
OFFSET...FETCH是在SQL Server 2012中新增的实现分页方式,OFFSET向SELECT查询表明跳过多少行,FETCH表明从特定的位置开始检索多少行。
示例:
SELECT [ProductID],[CategoryID],[ProductCode],[ProductName],[UnitPrice] FROM [dbo].[Product] ORDER BY [ProductID] OFFSET 10 ROWS FETCH NEXT 10 ROWS ONLY
使用OFFSET...FETCH限制:
◊ 使用OFFSET...FETCH子句必须同时使用ORDER BY。
◊ 可以单独使用OFFSET,但不能单独使用FETCH。
◊ 不可以同时使用SELECT TOP 和 OFFSET...FETCH。