Планировщик заданий в Oracle - Простой запуск задания
ОГЛАВЛЕНИЕ
Простой запуск задания
Простой запуск задания очень напоминает запуск с помощью процедуры SUBMIT из пакета DBMS_JOB. Однако он возможен, в отличие от SUBMIT, только при наличии привилегии CREATE JOB. В последующих примерах созданием заданий и управлением ими для простоты будет заниматься пользователь SCOTT, хотя в жизни разумно подумать об отдельном администраторе для этой цели. Выдадим нужную привилегию пользователю SCOTT:
CONNECT / AS SYSDBA
GRANT CREATE JOB TO scott;
Кроме системных привилегий использование планировщика регулируется объектными привилегиями EXECUTE, ALTER и ALL, выдача которых применительно (GRANT … ON) к заданию, программе, расписанию или классу заданий позволяет работать с объектами БД соответственно типов JOB, PROGRAM, SCHEDULE и JOB CLASS, введенных в Oracle 10 вместе с новым планировщиком.
Ввиду того, что в дальнейшем предполагаются эксперименты с изменениями зарплаты сотрудников, будет удобно исходную зарплату сохранить:
CONNECT scott/tiger
ALTER TABLE emp ADD ( oldsal NUMBER );
UPDATE emp SET oldsal = sal;
COMMIT;
Внутреннее задание для СУБД
Пример внутреннего задания в виде неименованого блока PL/SQL:
BEGIN
DBMS_SCHEDULER.CREATE_JOB
( job_name => 'simple_job'
, job_type => 'PLSQL_BLOCK'
, job_action => 'UPDATE emp SET sal = sal + 1;'
, enabled => TRUE
);
END;
/
Обратите внимание:
- Обрамлять блок словами BEGIN и END не обязательно, так как код пакета DBMS_SCHEDULER это сделает самостоятельно (ради особой программной логики, добавляемой им к тексту пользователя).
- Задание запускается в этом же сеансе и сопровождается неявной выдачей COMMIT. В этом легко удостовериться:
COMMIT;
UPDATE emp SET sal = sal + 1;
BEGIN DBMS_SCHEDULER.CREATE_JOB (... как выше ...) END;
ROLLBACK;
Зарплата SAL увеличится на 2. Проверить это в качестве упражнения.
Для хранимой процедуры задание формируется аналогично:
CREATE PROCEDURE updatesal AS BEGIN UPDATE emp SET sal = sal - 1; END;
/
BEGIN
DBMS_SCHEDULER.CREATE_JOB
( job_name => 'simple_job'
, job_type => 'STORED_PROCEDURE'
, job_action => 'updatesal'
, enabled => TRUE
);
END;
/
Обратите внимание, что нам не потребовалось удалять старое задание SIMPLE_JOB, так как при выбранных нами параметрах процедуры CREATE_JOB задания (и первое, и второе) прогонялись однократно, моментально и сразу же удалялись автоматически. Последнее как раз можно и отменить посредством не использованного в примере выше параметра AUTO_DROP. В случае невозможности запустить задание СУБД, подобно как для старого планировщика (пакет DBMS_JOB), будет делать повторные попытка, но только по несколько иной схеме: через секунду, затем через 10 секунд, затем через 100 и далее - всего 6 раз, если только до этого не наступит очередной плановый момент.
Внешнее задание (для ОС)
Совсем новым в планировщике Oracle 10 является возможность запускать плановые задания в ОС. Однако, чтобы это было возможно, в ОС должна быть запущена программа extjob из ПО СУБД. На Windows она запускается службой OracleJobScheduler<имя_СУБД>. Для того, чтобы следующий пример проработал, службу необходимо запустить. Вдобавок потребуется выдать пользователю SCOTT еще одну привилегию.
Пример запуска:
CONNECT / AS SYSDBA
GRANT CREATE EXTERNAL JOB TO scott;
CONNECT scott/tiger
BEGIN
DBMS_SCHEDULER.CREATE_JOB
( job_name => 'simple_job'
, job_type => 'EXECUTABLE'
, job_action => 'cmd.exe /C dir > \temp\out.txt'
, enabled => TRUE
);
END;
/
Обратите внимание, что в Windows выдача команды ОС, или же запуск командного файла напрямую (без вызова cmd.exe), не проходит.
В Unix аналогичное действие можно записать как 'ls > /tmp/out.txt'.
Возможности запуска, наблюдения, вмешательства
Так же, как для пакета DBMS_JOB, в новом планировщике предусмотрено именно плановое, а не одноразовое исполнение задания. Добавим к последнему вызову параметр:
, start_date => SYSTIMESTAMP + INTERVAL '10' SECOND
В результе корневой файл out.txt получим через 10 секунд после создания задания. Добавим еще параметр:
, repeat_interval => 'FREQ=MONTHLY; BYDAY=SUN, -1 SAT'
В результате задание будет исполняться ежемесячно по воскресениям и последним субботам месяца. В отличие от DBMS_JOB, DBMS_SCHEDULER, в дополнение к возможности употребить выражение на PL/SQL, имеет для формулирования графика запуска еще и специальный язык. Он позволяет указывать частоту, интервал и уточнитель запуска задания. Примеры:
FREQ=HOURLY;INTERVAL=4
- каждые 4 часа;
FREQ=HOURLY;INTERVAL=4;BYMINUTE=10;BYSECOND=30
- каждые 4 часа на 10-й минуте, 30-й секунде;
FREQ=YEARLY;BYYEARDAY=-276
- каждое 31-е марта;
FREQ=YEARLY;BYMONTH=MAR;BYMONTHDAY=31
- каждое 31-е марта;
Для проверки правильности составления выражения можно воспользоваться специальной процедурой:
DECLARE next_run_date TIMESTAMP;
BEGIN
DBMS_SCHEDULER.EVALUATE_CALENDAR_STRING (
'FREQ=HOURLY;INTERVAL=4;BYMINUTE=10;BYSECOND=30'
, SYSTIMESTAMP
, NULL
, next_run_date
);
DBMS_OUTPUT.PUT_LINE ( 'next_run_date: ' // next_run_date );
END;
/
Полное описание языка приводится в документации по Oracle.
Если указать план запуска, задание появится в системе уже надолго. Удалить его при необходимости можно будет так:
EXECUTE DBMS_SCHEDULER.DROP_JOB ( 'simple_job', TRUE )
Информация об имеющихся заданиях пользователь SCOTT может посмотреть запросом:
SELECT job_name, state, enabled FROM user_scheduler_jobs;
Более подробную информацию SCOTT обнаружит в таблицах USER_SCHEDULER_%, а более общую - в обычной таблице USER_OBJECTS.
