在SQL Server中进行分页

时间:2017-03-03 13:14:34

标签: sql-server

大家好帮我解决了这个问题。 我在SQL中有表名注释。 我在SQL过程中应用了分页。

  • 步骤1:首先我获取包含5条记录的第1页
  • 步骤2:现在创建新评论。
  • 步骤3:获取包含5条记录的第2页。
  • 步骤4:得到5行没问题,但我再次得到一条记录,这也是第1页

这是因为每次我创建新评论时,最后的评论将被移动一次,每次我都面临这种问题。

实施例

create proc getComments(@PageNumber tinyint,@PerPage INT,@TotalRecords INT OUTPUT)
AS
CREATE TABLE #TempTable
(RowNumber SMALLINT,Id int,CommentText nvarchar(max),CommentedBy nvarchar(256),CommentTime datetime

INSERT INTO #TempTable
    (RowNumber,Id ,CommentText ,CommentedBy ,CommentTime )
SELECT  ROW_NUMBER() OVER (ORDER BY CommentTime desc),Id,CommentText,CommentedBy ,CommentTime from comments
 SELECT @TotalRecords = COUNT(Id) FROM #TempTable

 SELECT * FROM #TempTable
    where RowNumber > (@PageNumber - 1) * @PerPage
    AND RowNumber <= @PageNumber * @PerPage 

GO

2 个答案:

答案 0 :(得分:0)

Sql server 2012引入了OFFSETFETCH子句,以便为分页查询结果提供简单的语法。我建议使用它。

另外,我建议阅读Aaron Bertrand的Pagination with OFFSET / FETCH : A better way文章,尤其是你遇到的分页性能问题。

CREATE PROCEDURE getComments (
    @PageNumber tinyint,
    @PerPage INT,
    @TotalRecords INT OUTPUT
)
AS

SELECT @TotalRecords = COUNT(Id) FROM comments;

SELECT Id, CommentText, CommentedBy ,CommentTime 
FROM comments
ORDER BY CommentTime desc
OFFSET (@PageNumber - 1) * @PerPage ROWS
FETCH NEXT @PerPage ROWS ONLY;

GO

答案 1 :(得分:0)

您的问题是您正在获得SQL中要求的内容。当您下次插入附加行时运行存储过程时,该行将被考虑在查询结果中。

防止新数据影响您的分页结果的唯一方法是删除新数据或从原始页面的最后一条记录再次开始分页。

这假设您的Id列是递增值。

CREATE PROC getComments(
    @PageNumber tinyint, @PerPage INT,
    @LastIdFromPreviousPage INT, @TotalRecords INT OUTPUT
)
AS
BEGIN
    CREATE TABLE #TempTable
    (RowNumber SMALLINT, Id INT, CommentText NVARCHAR(MAX),
        CommentedBy NVARCHAR(256),CommentTime DATETIME)

    INSERT INTO #TempTable
        (RowNumber, Id, CommentText, CommentedBy, CommentTime)
    SELECT
        ROW_NUMBER() OVER (ORDER BY CommentTime desc),
        Id, CommentText, CommentedBy, CommentTime
    FROM comments

    SELECT @TotalRecords = COUNT(Id) FROM #TempTable

    SELECT *
    FROM #TempTable
    WHERE (@LastIdFromPreviousPage IS NULL
        AND RowNumber > (@PageNumber - 1) * @PerPage
        AND RowNumber <= @PageNumber * @PerPage)
        OR (Id < @LastIdFromPreviousPage
            AND Id >= @LastIdFromPreviousPage - @PerPage)
END
GO

您还可以将@LastIdFromPreviousPage更改为第一次开始分页时的DATETIME,并在返回数据后过滤结果以在该日期之后开始分页。