none
Разделять результаты базы данных на страницы RRS feed

  • Вопрос

  • Добрый день,

    У нас идет поиск по базе данных и каждый результат на сиранице выходит в виде кнопки(asp:ImageButton).

    Мы хотим добавить возможность разделить результаты на пару страниц (например, 20 результатов на каждой странице).

    Какие методы есть для етого?

    Спасибо.

    19 ноября 2012 г. 8:38

Ответы

  • Вот Вам процедура для разбиения данных на сервере:

    CREATE PROCEDURE dbo.Pagination
    	@p_PageNumber INT, 
    	@p_PageSize INT,
    	@p_PageCount INT OUT 
    AS
    BEGIN
    	SELECT @p_PageCount = CEILING(CAST(COUNT(*) AS FLOAT)/ CAST(@p_PageSize AS FLOAT)) FROM dbo.People;
    	IF @p_PageNumber < 1
    		SET @p_PageNumber = 1;
        IF @p_PageSize < 1
    		SET @p_PageSize = 5;
    	SELECT TOP(@p_PageSize) * from (SELECT ROW_NUMBER() OVER(ORDER BY Id) AS Row, * FROM Test.dbo.People) as Tmp 
    	WHERE Row > (@p_PageNumber - 1) * @p_PageSize
    	end
    GO

    • Помечено в качестве ответа Andrey_ua 21 ноября 2012 г. 9:11
    • Снята пометка об ответе Andrey_ua 21 ноября 2012 г. 9:32
    • Помечено в качестве ответа Andrey_ua 21 ноября 2012 г. 9:39
    19 ноября 2012 г. 18:39
    Модератор
  • Так:

     IF @p_PageSize < 1
    		SET @p_PageSize = 5;
    	SELECT TOP(@p_PageSize) * from (SELECT ROW_NUMBER() OVER(ORDER BY Id) AS Row, * FROM Test.dbo.People) as Tmp 
    	WHERE Row > (@p_PageNumber - 1) * @p_PageSize AND category = 'a'
    	end

    • Помечено в качестве ответа Andrey_ua 21 ноября 2012 г. 9:39
    21 ноября 2012 г. 9:38
    Модератор

Все ответы

  • Если для вывода списка вы используете DataGrid, то у него есть замечательное свойство PageSize.

    19 ноября 2012 г. 9:03
    Отвечающий
  • Нет, не используем, так как нам просто результаты надо результаты в виде кнопок.

    Я не думаю что DataGrid нам пойдет.

    19 ноября 2012 г. 9:10
  • Для Вашего случая лучше всего подойдёт ListView, если конечно не хотите писать весь рутинный код сами.
    19 ноября 2012 г. 12:55
    Модератор
  • У меня таокй вопрос( не совсем в тему):

    Как можно, после получения результатов с базы данных, выбрать, например, от пятого до десятого результата?

    19 ноября 2012 г. 15:14
  • Если коллекция, которую вы используете, поддерживает интерфейс IEnuьerable, то добавив ссылку на пространство имен System.Linq, вы сможете воспользоваться методом Skip, чтобы пропустить часть последовательности, а потом методом Take, чтобы получить нужное количество элементов.

    Так, если у вас 10 элементов на страницу, то можно воспользоваться такой конструкцией:

    <коллекция для показа> = <исходная коллеция>.Skip(<номер страницы> * 10).Take(10);

    P.s. Подразумевается, что номер страницы начинается с нуля.
    19 ноября 2012 г. 16:07
    Отвечающий
  • У меня таокй вопрос( не совсем в тему):

    Как можно, после получения результатов с базы данных, выбрать, например, от пятого до десятого результата?

    Лучше так не делать, это неэффективно, особенно если данных много. Лучше прямо запросить столько, сколько нужно. Например через хранимую процедуру.
    19 ноября 2012 г. 16:52
    Модератор
  • Речь идет о результатах query (например select * from people where age= 20).

    Проблема в том что хотим разделить результаты на сайте на станицы (по 5, например).

    19 ноября 2012 г. 16:58
  • Лучше так не делать, это неэффективно, особенно если данных много. Лучше прямо запросить столько, сколько нужно. Например через хранимую процедуру.

    В большинстве случае да, но исходя из первого вопроса в топике, когда подразумевается целых две страницы результатов...
    19 ноября 2012 г. 17:00
    Отвечающий
  • Целых две страницы может быть и 10 елементов.
    19 ноября 2012 г. 17:11
  • Вот Вам процедура для разбиения данных на сервере:

    CREATE PROCEDURE dbo.Pagination
    	@p_PageNumber INT, 
    	@p_PageSize INT,
    	@p_PageCount INT OUT 
    AS
    BEGIN
    	SELECT @p_PageCount = CEILING(CAST(COUNT(*) AS FLOAT)/ CAST(@p_PageSize AS FLOAT)) FROM dbo.People;
    	IF @p_PageNumber < 1
    		SET @p_PageNumber = 1;
        IF @p_PageSize < 1
    		SET @p_PageSize = 5;
    	SELECT TOP(@p_PageSize) * from (SELECT ROW_NUMBER() OVER(ORDER BY Id) AS Row, * FROM Test.dbo.People) as Tmp 
    	WHERE Row > (@p_PageNumber - 1) * @p_PageSize
    	end
    GO

    • Помечено в качестве ответа Andrey_ua 21 ноября 2012 г. 9:11
    • Снята пометка об ответе Andrey_ua 21 ноября 2012 г. 9:32
    • Помечено в качестве ответа Andrey_ua 21 ноября 2012 г. 9:39
    19 ноября 2012 г. 18:39
    Модератор
  • А как этим пользоватся?
    19 ноября 2012 г. 18:42
  • Номер страницы и количество можете передать через скрытое поле или QueryString.
    19 ноября 2012 г. 18:42
    Модератор
  • А Вы вообще не использовали ADO.NET? Пример тут.

    19 ноября 2012 г. 18:45
    Модератор
  • Тогда Вам надо обязательно изучить, чтобы научиться работать с данными, в программировании, особенно в веб, без этого никак.
    19 ноября 2012 г. 19:31
    Модератор
  • А как такое решение?

    select * from designs order by id offset 11 rows FETCH NEXT 10 ROWS ONLY

    Это выдает 11-й по 20-й результат.

    20 ноября 2012 г. 10:37
  • Метод который привёл я - универсальный. Не надо ничего вычислять в выражении запроса, Вы всего лишь задаёте индекс страницы и номер. Остальное делает процедура.
    20 ноября 2012 г. 11:21
    Модератор
  • У меня  вопрос:

    adapter.InsertCommand.Parameters.Add("@CategoryName", SqlDbType.NChar, 15, "CategoryName");

    В вашем коде я меняю "@CategoryName" на "@p_PageNumber" (и на "@p_PageSize", " @p_PageCount"), а что я ставлю в последнем параметре?

    21 ноября 2012 г. 8:20
  • Вы не должны использовать adapter, используйте SqlCommand, для вызова хранимой процедуры. Ссылку на пример я дал высше.
    21 ноября 2012 г. 8:23
    Модератор
  • Я знаю, но что в тот параметр идет?

    Это мой код:

    SqlCommand com=new SqlCommand("Pagination",con);
    
                    com.CommandType=CommandType.StoredProcedure;
    
                    com.Parameters.Add(new SqlParameter("@p_PageNumber", SqlDbType.Int, 0, "?"));

    В вашей ссылке был adapter.

    21 ноября 2012 г. 8:30
  • Извиняюсь, не ту ссылку дал. Вот, а третий параметр должен быть Output, чтобы получить обратно PageCount.
    21 ноября 2012 г. 8:45
    Модератор
  • (Код так написан для тестирования)

    SqlParameter parameter = new SqlParameter();
                    parameter.ParameterName = "@p_PageNumber";
                    parameter.SqlDbType = SqlDbType.NVarChar;
                    parameter.Direction = ParameterDirection.Input;
                    parameter.Value = 1;
                    com.Parameters.Add(parameter);
    SqlParameter parameter2 = new SqlParameter();
                    parameter2.ParameterName = "@p_PageSize";
                    parameter2.SqlDbType = SqlDbType.NVarChar;
                    parameter2.Direction = ParameterDirection.Input;
                    parameter2.Value = 5;
                    com.Parameters.Add(parameter2);
    SqlParameter parameter3 = new SqlParameter();
                    parameter3.ParameterName = "@p_PageCount";
                    parameter3.SqlDbType = SqlDbType.NVarChar;
                    parameter3.Direction = ParameterDirection.Output;
                    com.Parameters.Add(parameter3);
                    con.Open();
                    SqlDataReader read = com.ExecuteReader();
    Вышодит ошибка: "String[2]: the Size property has an invalid size of 0."


    21 ноября 2012 г. 9:01
  • У Вас должно быть SqlDbType.Int, во всех трёх.
    21 ноября 2012 г. 9:05
    Модератор
  • ОК, все работает !

    Спасибо.

    21 ноября 2012 г. 9:10
  • У меня один вопрос:

    Мне не надо результаты всей таблицы, а только часть.

    SELECT * FROM table WHERE category=a

    Мне надо только одну категорию выводить.

    Как это добавить?


    • Изменено Andrey_ua 21 ноября 2012 г. 9:22
    21 ноября 2012 г. 9:18
  • Так:

     IF @p_PageSize < 1
    		SET @p_PageSize = 5;
    	SELECT TOP(@p_PageSize) * from (SELECT ROW_NUMBER() OVER(ORDER BY Id) AS Row, * FROM Test.dbo.People) as Tmp 
    	WHERE Row > (@p_PageNumber - 1) * @p_PageSize AND category = 'a'
    	end

    • Помечено в качестве ответа Andrey_ua 21 ноября 2012 г. 9:39
    21 ноября 2012 г. 9:38
    Модератор