Вопрос модификации SQL Proc - PullRequest
0 голосов
/ 27 июня 2011
ALTER PROCEDURE [dbo].[spGetMessages]
    @lastRow int
AS
BEGIN
    -- Insert statements for procedure here
    DECLARE @StartRow INT,@EndRow INT
    SELECT @StartRow = (@lastRow + 1), @EndRow = (@lastRow + 6)

;WITH cte AS (SELECT ROW_NUMBER() OVER (ORDER BY
        CASE WHEN @sort = 'votes1' THEN m.votes END DESC,
        CASE WHEN @sort = 'votes2' THEN m.votes END ASC,
        CASE WHEN @sort = 'age1' THEN datediff(minute,m.timestamp, getdate()) END ASC,
        CASE WHEN @sort = 'age2' THEN datediff(minute,m.timestamp, getdate()) END DESC
      ) AS rows,
      m.message,
      m.messageId
    FROM
      tblMessages m
    WHERE
      m.deleted != 1
      )
     SELECT * 
     FROM cte WHERE ROWS BETWEEN @StartRow AND @EndRow
    ORDER BY rows
END

Итак, этот процесс дает мне кучу сообщений, но с передачей значения последней строки, чтобы я мог реализовать пейджинг и функциональность «загрузить больше» во внешнем интерфейсе.

Если proc возвращает менее 6 сообщений, я могу, очевидно, отключить «загрузить больше», если он возвращает 6 сообщений, я не знаю, есть ли еще в базе данных или это были последние 6 сообщений.

Я думал, что если я передам обратно другой DataTable, содержащий либо true, либо false, который представлял бы, если в базе данных осталось более 6 этих сообщений с использованием последнего идентификатора строки, я мог бы использовать этот флаг для включить / отключить кнопку «загрузить еще». Это хорошая идея? Если нет, то какой план лучше?

Если это так, как бы я изменил этот процесс, чтобы передать этот флаг обратно?

Ответы [ 2 ]

2 голосов
/ 27 июня 2011

У нас есть несколько таких процедур.Простейшим способом было добавить дополнительный столбец в выводе с именем «TotalCount», который возвращал бы количество всех строк.

В вашем случае это выглядело бы так:

;WITH cte AS (SELECT ROW_NUMBER() OVER (ORDER BY
        CASE WHEN @sort = 'votes1' THEN m.votes END DESC,
        CASE WHEN @sort = 'votes2' THEN m.votes END ASC,
        CASE WHEN @sort = 'age1' THEN datediff(minute,m.timestamp, getdate()) END ASC,
        CASE WHEN @sort = 'age2' THEN datediff(minute,m.timestamp, getdate()) END DESC      ) AS rows,
            m.message, m.messageId,
        TotalCount = COUNT(m.Id) OVER ( PARTITION BY NULL)
    FROM tblMessages m
    WHERE m.deleted != 1
)
SELECT *
FROM cte 
WHERE ROWS BETWEEN @StartRow AND @EndRow
ORDER BY rows

I'mПредполагая, что tblMessages имеет столбец с именем Id.Смысл в том, чтобы просто посчитать уникальные идентификаторы в этой таблице.

Мы сделали это таким образом, чтобы нам не пришлось запускать 2 запроса.Конечно, в зависимости от размера данных это может оказать возможное влияние на производительность.Так что попробуйте оба способа.

======
Кстати, одна вещь, которая приходит на ум.Вы можете подумать о том, чтобы не использовать префиксы (например, «tbl» и «sp»). Это очень устаревший способ выполнения действий, который, как правило, совершенно не нужен.

0 голосов
/ 27 июня 2011

Вы можете использовать выходной параметр для отправки необходимой вам информации - может быть, общее количество строк, чтобы вы могли определить количество страниц для разбивки на страницы?Вы просто добавляете параметр OUTPUT в объявление proc:

ALTER PROCEDURE [dbo].[spGetMessages]
    @lastRow int,
    @yourFlagHere BIT OUTPUT

Я добавил BIT для поддержки вашей двоичной проверки, но вы можете использовать несколько других типов.Для получения дополнительной информации, проверьте Возврат данных с использованием параметров OUTPUT .Затем вы должны присвоить значение выходному параметру, вызвав proc с

EXEC dbo.spGetMessages @lastRowYouDefined, @yourFlagHere OUTPUT

. В вашем @yourFlagHere var будет определено значение, определенное в процедуре.

...