救命 !如何从SQL Server分页过程中获取总行数?

时间:2010-03-30 22:41:22

标签: sql-server-2005 data-paging

好的,我的SQL Server数据库中有一个用于存储注释的表。我的愿望是能够使用[Back],[Next],page number&我的数据列表中的[Last]按钮。我认为最有效的方法是使用只返回特定范围内的特定行数的存储过程。这就是我想出来的

@PageIndex INT, 
@PageSize INT,
@postid int


AS
 SET NOCOUNT ON  
 begin

WITH tmp AS ( 
SELECT comments.*, ROW_NUMBER() OVER (ORDER BY dateposted ASC)  AS  Row
    FROM    comments
    WHERE     (comments.postid = @postid))

SELECT tmp.*
FROM tmp
WHERE Row between 

(@PageIndex - 1) * @PageSize + 1 and @PageIndex*@PageSize

end

RETURN 

现在一切正常,我已经能够在我的数据列表寻呼机中实现[Next]和[Back]按钮。现在我需要所有注释的总数(不在当前页面中),以便我可以在我的寻呼机上实现我的页码和[Last]按钮。换句话说,我想在第一个选择语句中返回总行数,即

  WITH tmp AS ( 
    SELECT comments.*, ROW_NUMBER() OVER (ORDER BY dateposted ASC)  AS  Row
        FROM    comments
        WHERE     (comments.postid = @postid))
set @TotalRows = @@rowcount

@@ rowcount不起作用并引发错误。我也无法计算。*也可以工作。

是否有其他方法可以获得总行数或者我的方法注定失败了。

2 个答案:

答案 0 :(得分:5)

要获取页面的评论总数,需要单独的查询:

SELECT TotalRows = COUNT(*)
FROM comments
WHERE comments.postid = @postid

将此数据放回同一查询的唯一方法是将数据存储为主存储过程的子查询,并返回存储过程中每行的总数。

答案 1 :(得分:4)

我已经解决了这个问题,最后我发现了一些解决方案,但这些解决方案都不是很壮观,但却能完成这项工作:

  1. 查询两次
  2. 将计数作为其中一列返回
  3. 将结果存入临时表,同时将计数作为列返回
  4. 在第一个解决方案中,您可以执行以下操作:

        ...
        , @Count int OUTPUT
    AS 
    Select @Count = (
                    Select Count(*)
                    From comments
                    Where comments.postid = @postid
                        And Col1 = ... And Col2 = ...
                    )
    
    With NumberedResults As
        (
        Select ...
            , ROW_NUMBER() OVER( ORDER BY dateposted ASC ) As Num
        From comments
        Where Col1 = ... And Col2 = ...
        )
    Select ...
    From NumberedResults
    Where Num Between ( @PageIndex - 1 ) * @PageSize + 1 and @PageIndex * @PageSize
    

    明显的缺点是,如果查询很昂贵,那么你会做两次。

    在第二个解决方案中,您只需将计数作为结果的一部分返回。然后,您将从业务层代码中的第一条记录中选择计数。优点是您只需执行一次昂贵的查询。缺点是你为结果中的每一行返回额外的四个字节。

    With NumberedResults As
        (
        Select ...
            , ROW_NUMBER() OVER( ORDER BY dateposted ASC ) As Num
        From comments
        Where Col1 = ... And Col2 = ...
        )
    Select ...
        , ( Select Count(*) From NumberedResults ) As TotalCount
    From NumberedResults
    Where Num Between ( @PageIndex - 1 ) * @PageSize + 1 and @PageIndex * @PageSize
    

    第三个解决方案是第二个解决方案的变体,因为您将结果填入临时表并从第一个记录中设置out参数

        ...
        , @TotalCount int OUTPUT
    AS
    
    Declare @PagedResults Table (
                                Col1 ...
                                , ...
                                , TotalCount int
                                )
    With NumberedResults As
        (
        Select ...
            , ROW_NUMBER() OVER( ORDER BY dateposted ASC ) As Num
        From comments
        )
    Insert @PagedResults( Col1...., TotalCount )
    Select ...
        , ( Select Count(*) From NumberedResults ) As TotalCount
    From NumberedResults
    Where Num Between ( @PageIndex - 1 ) * @PageSize + 1 and @PageIndex * @PageSize
    
    Set @TotalCount = ( Select TOP 1 TotalCount From @PagedResults )
    
    Select ...
    From @PagedResults