У меня есть база данных "звезда". Один делает какую-то работу; у двух других есть задания, которые извлекают метаданные в свои справочные таблицы из первой базы данных. Я хочу запретить кому-либо обновлять, удалять или вставлять какие-либо записи в справочные таблицы в двух «рабах»; таблицы должны просто обновляться запланированным заданием.
В настоящее время я делаю это с помощью триггера, который проверяет, находится ли текущий SID в USER_SCHEDULER_RUNNING_JOBS с именем задания, которое, как я ожидаю, будет запущено. Я хотел бы изменить это, чтобы использовать JOB_ID задания, от которого я бегу.
Это моя текущая установка; предположим очень простую таблицу:
create table a ( b number );
и следующее задание:
begin
dbms_scheduler.create_job(
job_name => 'test_job'
, job_type => 'PLSQL_BLOCK'
, job_action => 'begin
merge into a a
using ( select 1 x from dual@db2 ) b
on (1 = 2)
when not matched then
insert values (b.x);
commit;
end;'
, start_date => sysdate
, repeat_interval => 'FREQ = MINUTELY;'
, enabled => true
);
end;
/
Я использую этот триггер:
create or replace trigger tr_blah
before insert or update on a
declare
l_ct number;
begin
select count(*) into l_ct
from user_scheduler_running_jobs
where session_id = sys_context('USERENV','SID')
and job_name = 'TEST_JOB'
;
if l_ct = 0 then
raise_application_error(-20000, 'FAIL');
end if;
end;
/
Это неэлегантно; но, что еще хуже, мне приходится создавать отдельный триггер для каждой таблицы в каждой базе данных и каждый раз менять имя задания. Невозможно динамически создать триггер; это становится утомительным, и есть много возможностей для ошибок.
SYS_CONTEXT()
имеет параметры FG_JOB_ID
и BG_JOB_ID
. Их описание, особенно описание FG_JOB_ID
, подразумевает, что они могут быть JOB_ID текущего задания. Изменение триггера на следующее (я пробовал оба):
create or replace trigger tr_a
before insert or update or delete on a
declare
l_ct number;
begin
raise_application_error(-20000, sys_context('USER_ENV', 'BG_JOB_ID'));
end;
/
Результаты в следующем
ORA-20000:
ORA-06512: at "REF.TR_A", line 4
ORA-04088: error during execution of trigger 'REF.TR_A'
ORA-06512: at line 2
Это означает, что и FG_JOB_ID
, и BG_JOB_ID
равны нулю. Есть ли метод определения идентификатора задания, работающего в текущем сеансе, чтобы мне не нужно было каждый раз использовать JOB_NAME?