Firebird: глобальные переменные

Как таковых глобальных переменных, определяемых пользователем, в Firebird нет и все пользуются таблицами вида: Options(key, value)
Но если у нас слишком много чтений, например в иерархично-вызываемых триггерах, то миллисекунды превращаются в сотни миллисекунд, а то и в секунды, что не есть хорошо

При помощи функции rdb$set_context можно к контекст пользователя поместить любое значение, и, по сути, закешировать его там
Чтение из контекста (rdb$get_context) осуществляется быстрее, чем чтение из таблицы

Пример использования ниже - функция по заданному ключу выдает значение, на типы прошу не обращать внимание, т.к. данное решение не унифицировано, а вытянуто из реального проекта


create or alter procedure
  GET_OPTION_CTX_VAL (OPTION_ID integer)
  returns (VAL D_MONEY)
as
begin
    val = rdb$get_context('USER_SESSION', 'opt' || option_id);

    if (val is null) then
    begin
     select value from options where key = :option_id into :val;
     rdb$set_context('USER_SESSION', 'opt' || :option_id, :VAL);
    end

    suspend;
end

В данной функции мы читаем значение из контекста и если оно не определено, то читаем из таблицы БД и помещаем его в контекст, чтобы при следующем обращении не обращаться к таблице

Пример использования вышеописанной функции:

select cast(val as integer) from GET_OPTION_CTX_VAL(401) into :base_step;

Мне это экономит от полусекунды и более, в зависимости от тяжеловесности области использования )

Крайне не рекомендую помещать в контекст изменяемые во время выполнения значения параметров

Комментариев нет:

Отправить комментарий

Можете оставить свой комментарий