Перегляньте відео нижче, щоб дізнатися, як встановити наш сайт як веб-програму на головному екрані.
Замітка: This feature may not be available in some browsers.
Знижка на баннерну рекламу 30%!
Банер на всіх сторінках сайту, в мобільній та десктопній версії за 14 тис. грн на місяць.
Статистика сайту.
Контакт: kharkovforum.com@gmail.com
Ви використовуєте застарілий браузер. Цей та інші сайти можуть відображатися в ньому некоректно. Необхідно оновити браузер або спробувати використовувати https://www.google.com/chrome/
Во! Тебя немножко позаганяешь стебом - ты начал читать.
Теперь внимание вопрос: совет читать не википедию а нормальные книжки по СУБД ты примешь в чистом виде или опять надо постебаться?
Возник вопрос. Для некоторых он очень прост, а у меня проблема. Есть DB с тысячами записей. Выборка происходит на стороне клиента через прогу. Сам запрос не важен, допустим что он стандартный на выборку всех полей из Представления. Необходим сам принцип вывода. Задача заключается в следующем, необходимо выводить по 20 (допустим) записей используя DataSet. Форма имеет кнопки предыдущий - следующий. При кликаньи на них происходит вывод следующих записей или предыдущих (собственно простой способ отображения информации в нете). Разработанный мною запрос очень плох. Кто то может написать необходимый запрос, или хотя бы подсказать направление.
Если речь идёт о Delphi и MSSQL'е, то можно сказать следующее.
Если есть только две указанные кнопки (предыдущий - следующий) и нет кнопки перехода к указанной "странице" то при выполнении следующего запроса пользователь всегда начинает просмотр с первой "страницы".
Подумаем, что происходит при выполнении следующего запроса?
Код:
SELECT a.T, a.E
FROM TE AS a
order by a.T
Сначала мы выполним TAdoQuery.Open() и получим первую строку из результирующего набора данных.
При этом не все строки с сервера попадут в память приложения.
Если пользователь нажмёт кнопку "следующая" - выполнится несколько вызовов TAdoQuery.Next() и в память приложения попадут следующие строки. Аналогично и с "листанием" данных в обратном направлении. Скорее всего, в памяти останутся те строки, которые пользователь просмотрел или пролистал. То есть для реализации такого интерфейса потребуется один серверный курсор на пользователя (+ память на просмотренные строки) и потребность ознакомиться с свойствами CacheSize, CursorType, CursorLocation, понятием "серверного курсора" и т.д.
Если очень хочется работать с отдельным запросом на "перелистывание страницы" (и требуется обеспечить возможность перейти на любую "страницу"), то можно применить другую технику:
1) перед показом формы создать временную (сессионную) таблицу и поместить в неё результат запроса упорядоченный по "страницам";
2) при показе данных определять номер требуемой "страницы" и с помощью временной таблицы получать только строки, расположенные на данной странице;
3) поскольку запрос на упорядочивание данных фактически выполняется только один раз - пользователь при "листании" всегда будет получать один и тот же набор строк (чего нельзя сказать о варианте с "top IND_").
Цена данного решения - место в temp'е.
P.S. Написано "по-памяти", фактические детали могут отличаться.
Для среднестатистической таблицы из нормализованной базы с продуманными индексами на низконагруженной системе кл-вом записей до одного ляма можно пренебречь.
SELECT a.T, a.E
FROM TE AS a
WHERE a.id not in (
select top IND_Вeg b.id
from te b
order by b.t
) AND a.id in (
select top IND_Еnd c.id
from te c
order by c.t
)
order by a.T
Проблема в том, что он делает три запроса - нагружает трафик.
Реально, благодарю что поправил. Так на самом деле - запрос и действительно обрабатывается только сервером. Но все же постает вопрос о нагрузке на сервер. Хорошее решение предложили с тригером. И eugene_kr предложил хороший метод, толко при обработки программно (то есть на клиентской машине). На сервере такое затруднит работу, а у клиента бутут старые данные (т.к. возможна ситуация запуска отчета и просмотра его до вечера, можно конечно поставить кнопку или таймер на обновление, но сори это не в моем вкусе (усложнение работы программы).
и потребность ознакомиться с свойствами CacheSize, CursorType, CursorLocation, понятием "серверного курсора" и т.д.
Ознакамливаться с курсорами у меня пока не было глубокой необходимости, т.к. из литературы я подчеркнул направление курсора для каких либо действий с определенной записью (Record), с ними работаю через AdoCommand.
На сервере такое затруднит работу, а у клиента бутут старые данные (т.к. возможна ситуация запуска отчета и просмотра его до вечера, можно конечно поставить кнопку или таймер на обновление, но сори это не в моем вкусе (усложнение работы программы).
Хранить во временной таблице нужно не данные, а ссылку (ключ) на строку отчёта и номер её "страницы" (фактически только страничную структуру отчёта). При показе "страницы" запрос будет вида "select ... from ... where a.id between IND_Вeg and IND_Еnd order by ...", где IND_Beg и IND_End берутся из временной таблицы на стороне сервера или из памяти приложения по номеру "страницы" отчёта. "Вычислительная сложность" такой конструкции будет самой простой из возможных для сервера в общем случае, если данные "отчёта" хранятся в таблице с соответствующим индексом, а не в представлении со сложным набором вычислений. По поводу описанной временной таблицы на сервере или в памяти приложения - зависит от условий задачи. Следует учесть, что описываемая таблица из двух полей (код строки, номер страницы) потребует не больше 12-20 байт на строку отчета. Здравый смысл подсказывает, что отчётов для просмотра людьми с 50000 строк фактически не бывает. Возьмём эту фантастическую цифру для примера. Это значит, что временная таблица потребует не более 1MB памяти (сервера или клиента) на отчёт из 50000 строк, а в случае отчёта из 100 строк - 2KB. Цифры приведены для примера, что бы оценить их порядок. Таким образом 10KB памяти сервера на просматриваемый пользователем отчёт (для среднего отчёта из 500 строк) - это не те накладные расходы, которые усложнят работу сервера (или клиентского приложения) в общем случае, а нагрузка при формировании и отображении "страниц" отчёта - минимальная из возможных.
Ознакамливаться с курсорами у меня пока не было глубокой необходимости, т.к. из литературы я подчеркнул направление курсора для каких либо действий с определенной записью (Record), с ними работаю через AdoCommand.
Настоятельно рекомендую, так как курсор есть то, к чему фактически предоставляет доступ TDataSet. В зависимости от того, каким методом и к какому курсору осуществляется доступ - появляются или исчезают различные возможности.
Вообще у любой задачи есть набор ограничений, которому должно удовлетворять решение. Если определить этот набор ограничений, то можно выделить определённый класс задач. Для определённого класса задач можно найти подходящие решения "в общем виде" специфичные для конкретного класса задач. Для задач без ограничений (задачи "в общем виде" или с неполным набором ограничений) есть только универсальные решения, практическое применение которых фактически невозможно из-за реально существующих ограничений.
В общем виде вывод из последнего абзаца следующий - либо потратить память (+ код (более сложная логика)) и получить результат "дешевле" (быстрее), либо не использовать дополнительную память (и код) и получить результат "дороже" (медленнее) при прочих равных условиях. Все практические решения - это компромисс между этими двумя крайностями.