Подкачка на всепроникающем SQL

#sql #pervasive

Вопрос:

Как выполнить подкачку в Pervasive SQL (версия 9.1)? Мне нужно сделать что-то подобное, например:

 //MySQL
SELECT foo FROM table LIMIT 10, 10
 

Но я не могу найти способ определить смещение.

Ответ №1:

Протестированный запрос в PSQL:

 select top n * 
from tablename 
where id not in(
select top k id
from tablename 
) 
 

для всех n = количество записей, которые вам нужно получить за один раз.
и k = кратные n(например, n=5; k=0,5,10,15,….)

Ответ №2:

Наша подкачка требовала, чтобы мы могли передать текущий номер страницы и размер страницы (вместе с некоторыми дополнительными параметрами фильтра) в качестве переменных. Так как select top @page_size не работает в MS SQL, мы придумали создать временную или переменную таблицу, чтобы присвоить первичному ключу каждой строки идентификатор, который позже можно будет отфильтровать для нужного номера и размера страницы.

** Обратите внимание, что если у вас есть первичный ключ GUID или составной ключ, вам просто нужно изменить идентификатор объекта во временной таблице на идентификатор uniqueid или добавить дополнительные ключевые столбцы в таблицу.

Недостатком этого является то, что он все равно должен вставить все результаты во временную таблицу, но, по крайней мере, это только ключи. Это работает в MS SQL, но должно работать для любой БД с минимальными настройками.

объявите @page_number int, @page_size int — добавьте любые дополнительные параметры поиска здесь

—создайте временную таблицу со столбцом идентификатора и идентификатором
-записи, которую вы будете выбирать. Это таблица в памяти
, поэтому, если количество строк, которые вы будете вставлять
, превышает 10 000, вместо этого вам следует использовать временную таблицу в базе данных tempdb
. Для этого используйте
—СОЗДАЙТЕ ТАБЛИЦУ #temp_table (ИДЕНТИФИКАТОР row_num int(1,1), objectid int)
—и измените все ссылки на @temp_table на #temp_table
ОБЪЯВИТЕ ТАБЛИЦУ @temp_table (ИДЕНТИФИКАТОР row_num int(1,1), objectid int)

—вставьте во временную таблицу идентификаторы записей
, которые мы хотим вернуть. Важно убедиться, что порядок по
-отражает порядок возврата записей, чтобы значения row_num
-были установлены в правильном порядке, и мы выбираем
—правильные записи на основе
ВСТАВКИ страницы В @temp_table (objectid)

/* Пример: Выберите, который вставляет записи во временную таблицу
ВЫБЕРИТЕ personid
ИЗ person С (NOLOCK)
внутренней степенью соединения С (NOLOCK) на degree.personid = person.personid
, ГДЕ person.lastname = @last_name
ПОРЯДОК ПО person.lastname asc, person.firsname asc
*/

—получить общее количество строк, которые у нас подобраны
объявить @total_rows инт
сет @total_rows = @@rowcount уже
—рассчитает количество страниц на количество
строк, —сочетается и размер листа, переданного в качестве параметра
объявить @total_pages инт
— добавить @размер_страницы — 1, к общему количеству строк
—рассчитает количество страниц. Это связано с тем, что sql
—alwasy округляет для деления целых
чисел НАБОР @total_pages = (@total_rows @page_size — 1) / @page_size

—верните интересующий нас результирующий набор, присоединившись
—назад к @temp_table и отфильтровав по номеру строки
/* Пример: Выбор данных для возврата. Если вставка была выполнена
правильно, то вы всегда должны присоединяться к таблице, содержащей
строки для возврата в столбец objectid в @temp_table

Выберите человек.*
От человека с (подсказку nolock) внутреннее соединение @temp_table ТТ
на человека.personid = ТТ.идентификатор ObjectId
*/
—вернуть только те строки, в разделе Что мы заинтересованы в
… и порядка в row_num столбец @temp_table, чтобы убедиться, что
мы-правильный выбор записей
, где ТТ.row_num < (@размер_страницы * @page_number) 1
и TT.row_num > (@размер_страницы * @page_number) — @размер_страницы
заказ по ТТ.row_num

Ответ №3:

Я тоже сталкиваюсь с этой проблемой в MS Sql… без ограничений или функций с номерами строк. Что я делаю, так это вставляю ключи для моего конечного результата запроса (или иногда весь список полей) во временную таблицу со столбцом идентификатора… затем я удаляю из временной таблицы все, что выходит за пределы диапазона, который я хочу… затем использую соединение с ключами и исходной таблицей, чтобы вернуть нужные мне элементы. Это работает, если у вас есть хороший уникальный ключ — если у вас его нет, что ж… это проблема дизайна сама по себе.

Альтернатива с немного лучшей производительностью-пропустить шаг удаления и просто использовать номера строк в вашем окончательном соединении. Еще одним улучшением производительности является использование ВЕРХНЕГО оператора, чтобы, по крайней мере, вам не нужно было хватать материал после окончания того, что вы хотите.

Итак… в псевдокоде… чтобы захватить предметы 80-89…

 create table #keys (rownum int identity(1,1), key varchar(10))

insert #keys (key)
select TOP 89 key from myTable ORDER BY whatever

delete #keys where rownumber < 80

select <columns> from #keys join myTable on #keys.key = myTable.key
 

Ответ №4:

В итоге я сделал подкачку в коде. Я просто пропускаю первые записи в цикле.

Я думал, что придумал простой способ разбиения на страницы, но, похоже, всепроникающий sql не допускает предложений порядка в подзапросах. Но это должно работать на других базах данных (я протестировал это на firebird)

 select *
from (select top [rows] * from
(select top [rows * pagenumber] * from mytable order by id)
order by id desc)
order by id