Помогите! Как получить общее количество строк из процедуры подкачки SQL Server?
Хорошо, у меня есть таблица в базе данных 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
Теперь все работает отлично, и я смог реализовать кнопки [Next] и [Back] в моем пейджере с списком данных. Теперь мне нужно общее количество всех комментариев (не на текущей странице), чтобы я мог ввести номера своих страниц и кнопку [Последняя] на своем пейджере. Другими словами, я хочу вернуть общее количество строк в моем первом операторе выбора, т.е.
WITH tmp AS (
SELECT comments.*, ROW_NUMBER() OVER (ORDER BY dateposted ASC) AS Row
FROM comments
WHERE (comments.postid = @postid))
set @TotalRows = @@rowcount
@@rowcount не работает и выдает ошибку. Я также не могу получить count.* На работу либо.
Есть ли другой способ получить общее количество строк или мой подход обречен.
2 ответа
Я имел дело с этой самой проблемой, и в конце концов я нашел несколько решений, ни одно из которых не впечатляет, но выполняет свою работу:
- Запрос дважды
- Возвратите счет как один из столбцов
- Запишите результаты во временную таблицу, возвращая счет в виде столбца.
В первом решении вы бы сделали что-то вроде:
...
, @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
Чтобы получить общее количество комментариев для страницы, потребуется отдельный запрос:
SELECT TotalRows = COUNT(*)
FROM comments
WHERE comments.postid = @postid
Единственный способ вернуть эти данные в тот же запрос - сохранить данные как подзапрос в основной хранимой процедуре и вернуть итоговое значение для каждой строки в хранимом процессе.