В некоторых случаях, при использовании sql, нужно ограничить выборку числа строк, указав с какой строки выдать и сколько строк выдать. Как сделать то же самое в Cache?Чтобы ограничить выборку, нам нужно передать в запрос два значения, начиная с какой строки результата запроса выдавать и сколько записей выдать. Такая задача характерна для выдачи данных постранично - один запрос, но выдать надо различные его части.
Используем хранимые процедуры и поведенческую модель движка cache. Если запросить в колонке результат хранимой процедуры так, что в ее параметрах не используются данные из таблиц, то cache вызывает ее однократно перед выполнением запроса. В нее и передадим первое значение - с какой строки выдавать записи. Второй параметр - сколько строк выдать - передадим в хранимую процедуру, использованную в условии where, причем так, что в ее параметр передается какая-либо колонка из таблицы. Это вынудит движок cache применять фильтрацию по этому условию. Мы, в хранимой процедуре, сверим количество обращений к ней и примем решение - подходит эта строка под выдачу или нет.
Так выглядит общая схема запроса:
select ID, LimitFrom( from_number) from table where LimitTo( table.ID, to_number)=1Используем локальную переменную для взаимодействия двух хранимых процедур:
ClassMethod LimitFrom(Arg1 As %String) As %String [ SqlProc ]
{
k zzzlimit
; счетчик обращений
s zzzlimit=0
; начальное значение для пропуска
s zzzlimit(1)=+$g(Arg1)
q ""
}
ClassMethod LimitTo(dummy, Arg1 As %String) As %Integer [ SqlProc ]
{
; увеличили счетчик заходов в фильтр LIMIT
i $i(zzzlimit)
; первые которые надо пропустить
i zzzlimit<zzzlimit(1) q 0
; концевые которые надо пропустить
i zzzlimit>(Arg1+zzzlimit(1)-1) q 0
; этот заход попадает в интервал
q 1
}
Эти две процедуры существуют сами по себе и не привязаны ни к какой таблице.
Чтобы не плодить лишних таблиц, я вписал их в класс Expand из заметки Cache':
Как развернуть значение параметра в несколько
строк и использовал из нее же условные данные, задаваемые извне. Поэтому
получил имена sql процедур, декорированные именем Expand:
>>select ID, Expand_Expand('g,h,j,k,f,e,d,c,b,a,1'),
Expand_LimitFrom(3) from
>>Expand where Expand_LimitTo(id,4)=1 order by ID
(1)>>go
b
c
d
e
>>
Здесь, для проверки запрашивается "выдать с третьей строки select четыре строки".
Очевидно, что если задать "выдать с первой строки", то получим функциональный
аналог TOP 4.
К плюсам полученного решения я отнесу тот факт, что если в запросе стоит order by, то движок каше сначала применяет сортировку, и после нее фильтрацию, применив хранимую функцию. К минусам - то, что хранимые процедуры используют одну и ту же локальную переменную и нельзя использовать несколько ограничений в одном сложном запросе.
Комментариев нет:
Отправить комментарий