В некоторых случаях, при использовании 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, то движок каше сначала применяет сортировку, и после нее фильтрацию, применив хранимую функцию. К минусам - то, что хранимые процедуры используют одну и ту же локальную переменную и нельзя использовать несколько ограничений в одном сложном запросе.
Комментариев нет:
Отправить комментарий