Помогите ! Как получить общее количество строк из процедуры подкачки SQL Server? - PullRequest
3 голосов
/ 31 марта 2010

Хорошо. В моей базе данных SQL Server есть таблица, в которой хранятся комментарии. Я хочу иметь возможность просматривать страницы, используя записи [Back], [Next], номера страниц и [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 

Теперь все работает нормально, и мне удалось внедрить кнопки [Далее] и [Назад] в мой пейджер списка данных. Теперь мне нужно общее количество всех комментариев (не на текущей странице), чтобы я мог ввести номера своих страниц и кнопку [Последняя] на своем пейджере. Другими словами, я хочу вернуть общее количество строк в моем первом операторе выбора, т. Е.

  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 ]

5 голосов
/ 31 марта 2010

Чтобы получить общее количество комментариев для страницы, потребуется отдельный запрос:

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

Единственный способ вернуть эти данные в тот же запрос - сохранить данные как подзапрос в основной хранимой процедуре и вернуть итоговое значение для каждой строки в хранимой процедуре.

4 голосов
/ 31 марта 2010

Я имел дело с этой самой проблемой, и в конце концов я нашел несколько решений, ни одно из которых не является впечатляющим, но выполняет работу:

  1. Запрос дважды
  2. Возвращает счетчик в качестве одного из столбцов
  3. Запишите результаты во временную таблицу, возвращая счет в виде столбца

В первом решении вы бы сделали что-то вроде:

    ...
    , @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
...