Мне нравится использовать короткий, но интуитивно понятный синтаксис и, таким образом, можно создать, например, некоторый ctx
пакет , который просто предоставляет одну функцию для установки и получения глобальных «переменных» .
(действительно только для текущего сеанса; в моем случае нет необходимости реализовывать его как переменные контекста, созданные пользователем, но его легко заменить на него; пример с некоторыми foo varchar2
и bar number
переменными)
использование
select ctx.foo from dual -- => null (init)
select ctx.foo('a') from dual -- => 'a'
select ctx.foo('b') from dual ; select ctx.foo from dual -- => 'b', 'b'
.
-- (optimizer should cause the subquerys unselected columns not to be executed:)
select 'ups' from (select ctx.foo('a') from dual) ; select ctx.foo from dual -- => null
select ctx.bar(1.5) from dual ; select ctx.bar from dual -- => 1.5, 1.5
-- ...
заголовок пакета :
create or replace package ctx as
-- select ctx.foo from dual -- => null (init)
-- select ctx.foo('a') from dual -- => 'a'
-- select ctx.foo('b') from dual ; select ctx.foo from dual -- => 'b', 'b'
-- (optimizer should cause the subquerys unselected columns not to be executed:)
-- select 'ups' from (select ctx.foo('a') from dual) ; select ctx.foo from dual
-- => null
-- parallel_enable for queries since it should not change inside of them
function foo( set varchar2 := null ) return varchar2 parallel_enable;
-- (samples like in foo above as executable test comments like in foo above skipped for
-- brevity)
function bar( set number := null ) return number parallel_enable;
end;
корпус упаковки :
create or replace package body ctx as
foo_ varchar2(30); -- e.g. 'blabla'
bar_ number;
-- internal helper function for varchars
function set_if_not_null( ref in out varchar2, val varchar2 ) return varchar2 as
begin
if val is not null then ref := val; end if;
return ref ;
end;
-- internal helper function for numbers
function set_if_not_null( ref in out number, val number ) return number as begin
if val is not null then ref := val; end if;
return ref ;
end;
-- (same test comments like in foo above skipped for brevity)
function foo( set varchar2 := null ) return varchar2 parallel_enable as begin
return set_if_not_null( foo_, set ) ;
end;
-- (same test comments like in foo above skipped for brevity)
function bar( set number := null ) return number parallel_enable as begin
return set_if_not_null( bar_, set ) ;
end;
end;
Если вы знаете, что переменная (foo
) может измениться в пределах одного запроса, то удалите parallel_enable
, который в противном случае должен быть более производительным, если запросы распараллеливаются.
В зависимости от потребностей, можно, конечно, добавить foo_reset()
, чтобы установить его на ноль и т. Д.