DeepEdit!

Программирование баз данных на Oracle, техническая документация, литература, статьи и публикации

  • Увеличить размер шрифта
  • Размер шрифта по умолчанию
  • Уменьшить размер шрифта

Удаление задания

Если в задании больше нет необходимости, его можно удалить при помощи процедуры DROP_JOB. Удалим, например, задание APPLY_DAILY_IN- TEREST:
Управление календарем и расписанием
Предыдущий раздел был посвящен первому из четырех основных компонентов планировщика: заданию. В этом разделе изучим второй ключевой (и наиболее заметный) компонент - расписание, определяющее моменты времени, когда предполагается запускать задание. Расписание можно указать при создании задания в процедуре CREATE_JOB, задав календарную строку в качестве значения параметра repeat_interval или сославшись на уже созданное именованное расписание.
Календарные строки
Синтаксис использования календарной строки для значения параметра repeat_interval процедуры CREATE_JOB чрезвычайно прост, особенно для знающих английский язык. Например, если вы определяете задание, которое выполняется с понедельника по пятницу ровно в 7 часов утра и 3 часа дня, то значением параметра repeat_interval может быть такая календарная строка:

Календарная строка включает в себя два разных по типу предложения: FREQ и BY, разделенные точкой с запятой. Предложение FREQ может быть ровно одно, а предложений BY может быть несколько разных видов, в зависимости от конкретного расписания. Каждое предложение состоит из ключевого слова и значения, которые разделены знаком равенства. Все вместе эти предложения указывают, как часто планируется выполнять задание.
Частота (FREQ)
Предложение FREQ задает интервал между повторными выполнениями. В нашем случае задание должно повторяться каждый день, поэтому FREQ = DAILY. Допустимы следующие ключевые слова: YEARLY, MONTHLY, WEEKLY, DAILY, HOURLY, MINUTELY и SECONDLY.
Сроки (BY...)
Если задание в текущий момент выполняется, то будет возвращена ошибка. Если же задать параметр FORCE, то планировщик сначала попытается остановить задание, а затем удалить его:
Предложение BY определяет, когда именно задание будет выполняться. В примере, определяя частоту выполнения, мы указали, что зада-
ние выполняется ежедневно (FREQ=DAILY). Теперь следует ограничить множество дней (задание должно выполняться только в рабочие дни), указав BYDAY=MON,TUE,WED,THU,FRI. Далее необходимо потребовать, чтобы задание запускалось в 7 часов утра и в 3 часа дня, указав BY- HOUR=7,15. Разрешены следующие ключевые слова: BYMONTH, BYMONTHDAY, BYYEARDAY, BYHOUR, BYMINUTE и BYSECOND (см. описание в табл. 8.1).
Предположим, что задание следует запускать ежедневно (вне зависимости от дня недели) в 10 часов утра, в 2 часа дня и в 8 часов вечера. Тогда параметр repeat_interval может быть таким:
FREQ=DAILY; BYHOUR=10,14,20
Что делать, если задание необходимо выполнять через день, а не каждый день? Используем новое ключевое слово - INTERVAL:
FREQ=DAILY; INTERVAL=2, BYHOUR=10,14,20
Предложение INTERVAL=2 изменяет частоту вдвое по отношению к значению, указанному в предложении FREQ. В нашем случае FREQ=DAILY, поэтому задание будет выполняться каждые два дня.
Отрицательные значения означают отсчет от конца периода. Например, следующая строка задает второй час, начиная с конца дня:
FREQ=DAILY; BYHOUR=-2
Некоторые основные интервальные команды для параметра repeat_in- terval собраны в табл. 8.1.
Таблица 8
.1. Ключевые слова BY для календарных строк в параметре repeat_interval
Ключевое слово
Описание
BYMONTH

Планирование выполнение задания в определенные меся­цы. Например, для того чтобы задание вычисления процен­тов выполнялось только в июне и декабре, задаем:
BYMONTH=JUN,DEC
Можно использовать не только названия, но и номера меся­цев:
BYMONTH=6,12
Точная дата внутри месяца, когда задание будет выполнено, совпадает с днем его запуска. Например, если задание запус­кается 4 июля, то в декабре и в июне оно будет выполнено 4 числа. Если необходимо, чтобы задание выполнялось в дру­гой день, следует использовать ключевое слово BYMONTHDAY.
BYMONTHDAY

Указывает, в какой именно день месяца должно выполнять­ся задание. Например, для выполнения задания первого числа каждого месяца в 3 часа дня указываем:
FREQ=MONTHLY; BYMONTHDAY=1; BYHOUR=15
Если опустить предложение BYHOUR, задание по умолчанию будет выполняться в полночь.

Ключевое слово
Описание
BYYEARDAY
Указывает, в какой день года должно выполняться задание. Например, для выполнения задания в пятнадцатый день ка­

ждого года задаем:


FREQ=YEARLY; BYYEARDAY=15
BYHOUR
Планирование выполнения задания в определенные часы. Например, для каждодневного выполнения задания в 3, 6 и 9 часов утра задаем:
FREQ=DAILY; BYHOUR=3,6,9 Расписание, основанное на такой календарной строке, будет выглядеть следующим образом:

07/06/2005 03
00
00

07/06/2005 06
00
00

07/06/2005 09
00
00

07/07/2005 03
00
00

07/07/2005 06
00
00

07/07/2005 09
00
00

... и так далее.


Можно изменить предыдущий пример следующим образом:

FREQ=MINUTELY;
BYHOUR=3,6,9

Частота MINUTELY
означает, что задание будет выполняться

каждую минуту. В этом случае расписание будет таким:

07/06/2005 03
00
00

07/06/2005 03
01
00

07/06/2005 03
02
00

07/06/2005 03
03
00

07/06/2005 03
04
00

07/06/2005 03
05
00

... и так далее до 03:59:00. Последовательность будет повто­

рена в 6:00:00 вечера и будет длиться до 06:59:00 вечера.
BYMINUTE
Планирование выполнения задания в определенную мину­ту. Для выполнения задания каждые полчаса задаем такую календарную строку:

FREQ=MINUTELY;
BYMINUTE=30

Расписание, основанное на такой календарной строке, будет

выглядеть следующим образом:

07/06/2005 00
30
00

07/06/2005 01
30
00

07/06/2005 02
30
00

... и так далее.


Если в данном случае написать FREQ=HOURLY вместо MINUTELY,

то ничего не изменится, так как составляющая часа не ука-

зывается. Однако если задать такую строку:

FREQ=DAILY; BYMINUTE=30

Ключевое слово
Описание

округление будет вестись с точностью до дня. Поэтому рас-

писание будет следующим:

07/06/2005 00:30:00

07/07/2005 00:30:00

07/08/2005 00:30:00

07/09/2005 00:30:00

... и так далее.

Здесь задание выполняется каждый день в 00:30, так как

в предложении FREQ указано DAILY.
BYSECOND
Аналогично BYMINUTE и BYHOUR, ключевое слово BYSECOND слу­жит для планирования выполнения задания в определен­ную секунду.

Отрицательное значение какого-то ключевого слова означает отсчет от конца (а не от начала) периода. Например, следующая календарная строка
FREQ=YEARLY; BYYEARDAY=-1
указывает на первый день года, начиная с его конца. Поэтому такое задание будет выполняться каждый год 31 декабря.
Примеры календарных строк
Давайте рассмотрим еще несколько примеров календарных строк. Предположим, что все они изначально указаны для заданий, запускаемых 5 июля 2005 года. Покажем, как задавать календарные строки, начиная с определения больших интервалов, а затем переходя к более мелким.
FREQ=YEARLY
Задано ежегодное выполнение, так что задание будет работать один раз в год. Никакие даты не указаны, так что по умолчанию задание будет выполняться 5 июля каждый год, начиная с 2006. Это задание будет выполняться каждый год 5 июля в полночь.
FREQ=YEARLY; INTERVAL=2
Использовано предложение INTERVAL, поэтому формируется расписание для выполнения не каждый год, а через год. Данное задание будет выполнено 5 июля в 2007 году, 2009, 2011 и т. д.
FREQ=YEARLY; BYMONTH=JAN
Наличие предложения BYMONTH означает, что ежегодное выполнение задания не будет по умолчанию приходиться на текущий месяц (июль). Но так как конкретная дата не указана, день все-таки будет взят по умолчанию - пятое число. Таким образом, это задание будет выполняться ежегодно 5 января (опять-таки в полночь).
FREQ=YEARLY; BYMONTH=JAN; BYMONTHDAY=2
Обратите внимание на дополнительное предложение BYMONTHDAY. Оно указывает на то, что расписание будет действовать для второго дня месяца (а не для дня, предусмотренного по умолчанию). Это задание будет выполняться 2 января 2006 года, 2 января 2007 года и т. д.
FREQ=YEARLY; BYMONTH=JAN; BYDAY=SUN
Здесь вместо даты указан день недели внутри определенного месяца. Такое задание будет выполняться ежегодно каждое воскресенье января. Приведем несколько дат выполнения в формате мм/дд/гггг:

Все это воскресенья.
FREQ=YEARLY; BYMONTH=JAN; BYMONTHDAY=2; BYDAY=SUN
Скомбинируем два предыдущих примера расписания. Предложение BYMONTHDAY задает определенный день месяца (второй), а предложение BYDAY - определенный день недели (воскресенье). Поэтому задание будет выполняться каждое воскресенье января, если оно выпадет на 2-е число. Расписание будет таким:

Первый раз задание будет выполнено 2 января 2011, так как это воскресенье.
FREQ=YEARLY; BYYEARDAY=60
Запрошено выполнение задания каждый 60-й день года. Расписание выглядит следующим образом:

Обратите внимание, что планировщик учел високосность 2008 года: в нем 60-й день выпадает на 29 января. В остальных случаях шестидесятым днем года является 1 марта.

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


Как видите, 2008 год исключен. В этом году 60-й день выпадает на 29 февраля (то есть не на первый день месяца), поэтому год не включается в расписание.
FREQ=YEARLY; BYWEEKNO=2
Указываем, что задание должно выполняться каждый день второй недели года. Расписание будет таким:

Все семь дней второй недели каждого года присутствуют в расписании.
FREQ=DAILY; BYHOUR=3,6,9
Это задание выполняется ежедневно ровно в три, шесть и девять часов утра.

К предыдущим условиям добавлено предложение INTERVAL=2. Это означает, что интервал между двумя последовательными выполнениями должен быть вдвое больше интервала, указанного в предложении FREQ (то есть в нашем случае должен составлять 2 дня).

Задание выполняется 6 июля, затем 8 июля.
FREQ=DAILY; BYHOUR=3,6,9; BYMINUTE=00,15,30,45
Это задание, как и предыдущее, выполняется ежедневно в 3, 6 и 9 часов дня, но наличие предложения BYMINUTE указывает на то, что задание должно выполняться в указанные минуты. Так что расписание будет выглядеть так:

Нумерация недель ISO-8601

Если использовано ключевое слово BYWEEKNO, то планировщик применяет нумерацию недель, зафиксированную в стандарте IS0-8601 и имеющую ряд специфических особенностей. Вот что вам необходимо знать о нумерации недель согласно IS0-8601:
Первым днем недели считается не воскресенье, а понедельник, так как именно такой порядок принят во многих компаниях и программах.
Недели имеют номера от 1 до 53.
Первая неделя начинается в первый понедельник года. Следовательно, несколько дней могут предшествовать первой неделе года. Например, если в 2005 году ваша календарная строка выглядит как «FREQ=YEARLY; BYWEEKNO=1», то это расписание начнет действовать 2 января 2005, так как это и будет первый понедельник 2005 года. Это означает, что 1 января никогда не появится ни в одном из расписаний. Возможно, для вас это и не важно, но следует иметь это в виду.
Аналогично последняя неделя года может захватывать не все дни. Часть года может остаться вне последней недели: она будет включена в первую неделю следующего года.
Последняя неделя года может содержать часть следующего года. Рассмотрим календарную строку «FREQ=YEARLY; BYWEEKNO=52». Если она задается в 2005 году, то будет составлено такое расписание:

• Обратите внимание, что последняя неделя года включает в себя 1 января 2006 года, которое относится к 2006, а не 2005 году. Хотя неделя и считается 52-й неделей 2005 года, фактически расписание заходит в 2006 год. Если при составлении расписания вы не будете учитывать такую возможность, то результат может оказаться далеким от ожидаемого.
Календарные строки для дат в будущем
Календарные строки так похожи на обычный английский язык, что писать их не составляет труда. Однако можно случайно что-то перепутать, и в результате расписание окажется не таким, как предполагалось. Процедура EVALUATE_CALENDAR_STRING пакета DBMS_SCHEDULER анализирует календарные строки и формирует тестовое расписание, которое можно тщательно изучить и убедиться в том, что задание будет выполняться так, как предполагалось.
Процедура принимает четыре параметра:
calendar_string
Обрабатываемая календарная строка.
start_date
Дата (в виде значения типа TIMESTAMP), с которой следует начать.
return_date_after
Если необходимо указывать даты и моменты времени, стоящие после какой-то определенной даты, то используйте этот параметр для начала последовательности планируемых после данной даты дат.
next_run_date
Это выходной параметр. Процедура записывает в него дату и время, когда планировщик будет выполнять данную календарную строку.
Давайте рассмотрим пример использования этой процедуры для получения расписания выполнений задания для календарной строки
«FREQ=MONTHLY;INTERVAL=2».


Просмотрев точные даты и моменты времени будущих выполнений задания, вы сможете проверить, совпадают ли они с ожидаемыми.
Именованные расписания
Календарные строки очень полезны при составлении расписания выполнения ваших заданий. Но предположим, что существует несколько заданий, выполняющихся одновременно (например, сбор статистики оптимизатора для нескольких таблиц). Приведем фрагмент представления словаря данных, отображающий расписание для таких заданий:

Как видите, все задания имеют одну и ту же календарную строку - «FREQ=DAILY; BYHOUR=3», которая означает ежедневное выполнение задания в 3 часа дня. Если теперь нужно будет изменить время с 3 часов на 4 - что вы будете делать?
Придется очень аккуратно пройтись по всем календарным строкам и изменить каждую из них. Чем больше заданий, чем больше работы придется проделать; это будет весьма утомительно, и к тому же возможны ошибки. Это общий недостаток любого жесткого кодирования внутри приложения.
Планировщик позволяет избежать жесткого кодирования за счет создания именованного расписания, на которое смогут ссылаться все задания. При использовании именованного расписания нет необходимости в явном указании календарной строки: поддержка расписания значительно упрощается. Давайте посмотрим, как это работает.
Используя процедуру CREATE_SCHEDULE, создаем расписание с именем opt_ stat_coll_sched, которое задает приведенную ранее календарную строку


Теперь посмотрим на строки подробно.
Строка
Описание
3
Имя расписания.
4
Время начала действия именованного расписания. В этом примере расписание должно начинать действовать в текущий момент. Время должно задаваться как значение типа TIMESTAMP, поэтому использова­но значение SYSTIMESTAMP вместо SYSDATE.
5
Календарная строка, определяющая расписание.
6
Комментарии, описывающие расписание.

После того как расписание создано, сценарий создания задания может на него ссылаться по имени. Давайте удалим уже созданные задания и начнем заново:
Код практически идентичен коду предыдущего фрагмента создания задания. Отличие имеется в строке 5, где появляется новый параметр: schedule_name, в котором можно ссылаться на только что созданное расписание.
Удаляем все задания и пересоздаем их с использованием именованного расписания. Вот пример для задания TABSTAT_SAVINGS.
Для того чтобы проверить сопоставленное заданию расписание, можно (как и раньше) обратиться к представлению словаря данных DBA_SCHED- ULER_JOBS. Предположим, что задание TABSTAT_SAVINGS создано заново с использованием именованного расписания. Два других задания все еще сопоставлены календарным строкам.

Как видите, столбец SCHEDULE_TYPE отображает значение NAMED для задания, которому было сопоставлено именованное расписание. Для остальных заданий (продолжающих использовать календарные строки) в этом столбце выводится значение CALENDAR. Столбец SCHEDULE_NAME содержит имя расписания, сопоставленного заданию. Кроме того, при сопоставлении заданию именованного расписания столбец REPEAT_IN- TERVAL для такого задания устанавливается в значение NULL.
 









jAntivirus