Если в задании больше нет необходимости, его можно удалить при помощи процедуры 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
|
|||
Планирование выполнения задания в определенные часы. Например, для каждодневного выполнения задания в 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 вечера.
|
|||
Планирование выполнения задания в определенную минуту. Для выполнения задания каждые полчаса задаем такую календарную строку:
|
|||
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.
|
|
Аналогично BYMINUTE и BYHOUR, ключевое слово BYSECOND служит для планирования выполнения задания в определенную секунду.
|
Отрицательное значение какого-то ключевого слова означает отсчет от конца (а не от начала) периода. Например, следующая календарная строка
FREQ=YEARLY; BYYEARDAY=-1
указывает на первый день года, начиная с его конца. Поэтому такое задание будет выполняться каждый год 31 декабря.
Давайте рассмотрим еще несколько примеров календарных строк. Предположим, что все они изначально указаны для заданий, запускаемых 5 июля 2005 года. Покажем, как задавать календарные строки, начиная с определения больших интервалов, а затем переходя к более мелким.
FREQ=YEARLY
Задано ежегодное выполнение, так что задание будет работать один раз в год. Никакие даты не указаны, так что по умолчанию задание будет выполняться 5 июля каждый год, начиная с 2006. Это задание будет выполняться каждый год 5 июля в полночь.
Использовано предложение INTERVAL, поэтому формируется расписание для выполнения не каждый год, а через год. Данное задание будет выполнено 5 июля в 2007 году, 2009, 2011 и т. д.
Наличие предложения BYMONTH означает, что ежегодное выполнение задания не будет по умолчанию приходиться на текущий месяц (июль). Но так как конкретная дата не указана, день все-таки будет взят по умолчанию - пятое число. Таким образом, это задание будет выполняться ежегодно 5 января (опять-таки в полночь).
Обратите внимание на дополнительное предложение BYMONTHDAY. Оно указывает на то, что расписание будет действовать для второго дня месяца (а не для дня, предусмотренного по умолчанию). Это задание будет выполняться 2 января 2006 года, 2 января 2007 года и т. д.
Здесь вместо даты указан день недели внутри определенного месяца. Такое задание будет выполняться ежегодно каждое воскресенье января. Приведем несколько дат выполнения в формате мм/дд/гггг:
Все это воскресенья.
FREQ=YEARLY; BYMONTH=JAN; BYMONTHDAY=2; BYDAY=SUN
Скомбинируем два предыдущих примера расписания. Предложение BYMONTHDAY задает определенный день месяца (второй), а предложение BYDAY - определенный день недели (воскресенье). Поэтому задание будет выполняться каждое воскресенье января, если оно выпадет на 2-е число. Расписание будет таким:
Первый раз задание будет выполнено 2 января 2011, так как это воскресенье.
Запрошено выполнение задания каждый 60-й день года. Расписание выглядит следующим образом:
Обратите внимание, что планировщик учел високосность 2008 года: в нем 60-й день выпадает на 29 января. В остальных случаях шестидесятым днем года является 1 марта.
Комбинируя условия, можно получить интересующие нас результаты. Пусть задание выполняется в 60-й день года и в первый день месяца. Получаем такое расписание:
Как видите, 2008 год исключен. В этом году 60-й день выпадает на 29 февраля (то есть не на первый день месяца), поэтому год не включается в расписание.
Указываем, что задание должно выполняться каждый день второй недели года. Расписание будет таким:
Все семь дней второй недели каждого года присутствуют в расписании.
Это задание выполняется ежедневно ровно в три, шесть и девять часов утра.
К предыдущим условиям добавлено предложение INTERVAL=2. Это означает, что интервал между двумя последовательными выполнениями должен быть вдвое больше интервала, указанного в предложении FREQ (то есть в нашем случае должен составлять 2 дня).
Задание выполняется 6 июля, затем 8 июля.
Это задание, как и предыдущее, выполняется ежедневно в 3, 6 и 9 часов дня, но наличие предложения BYMINUTE указывает на то, что задание должно выполняться в указанные минуты. Так что расписание будет выглядеть так:
Если использовано ключевое слово 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
Если необходимо указывать даты и моменты времени, стоящие после какой-то определенной даты, то используйте этот параметр для начала последовательности планируемых после данной даты дат.
Это выходной параметр. Процедура записывает в него дату и время, когда планировщик будет выполнять данную календарную строку.
Давайте рассмотрим пример использования этой процедуры для получения расписания выполнений задания для календарной строки
«FREQ=MONTHLY;INTERVAL=2».
Просмотрев точные даты и моменты времени будущих выполнений задания, вы сможете проверить, совпадают ли они с ожидаемыми.
Календарные строки очень полезны при составлении расписания выполнения ваших заданий. Но предположим, что существует несколько заданий, выполняющихся одновременно (например, сбор статистики оптимизатора для нескольких таблиц). Приведем фрагмент представления словаря данных, отображающий расписание для таких заданий:
Как видите, все задания имеют одну и ту же календарную строку - «FREQ=DAILY; BYHOUR=3», которая означает ежедневное выполнение задания в 3 часа дня. Если теперь нужно будет изменить время с 3 часов на 4 - что вы будете делать?
Придется очень аккуратно пройтись по всем календарным строкам и изменить каждую из них. Чем больше заданий, чем больше работы придется проделать; это будет весьма утомительно, и к тому же возможны ошибки. Это общий недостаток любого жесткого кодирования внутри приложения.
Планировщик позволяет избежать жесткого кодирования за счет создания именованного расписания, на которое смогут ссылаться все задания. При использовании именованного расписания нет необходимости в явном указании календарной строки: поддержка расписания значительно упрощается. Давайте посмотрим, как это работает.
Используя процедуру CREATE_SCHEDULE, создаем расписание с именем opt_ stat_coll_sched, которое задает приведенную ранее календарную строку
Теперь посмотрим на строки подробно.
|
|
Строка
|
Описание
|
3
|
Имя расписания.
|
4
|
|
5
|
Календарная строка, определяющая расписание.
|
6
|
Комментарии, описывающие расписание.
|
После того как расписание создано, сценарий создания задания может на него ссылаться по имени. Давайте удалим уже созданные задания и начнем заново:
Код практически идентичен коду предыдущего фрагмента создания задания. Отличие имеется в строке 5, где появляется новый параметр: schedule_name, в котором можно ссылаться на только что созданное расписание.
Удаляем все задания и пересоздаем их с использованием именованного расписания. Вот пример для задания TABSTAT_SAVINGS.
Для того чтобы проверить сопоставленное заданию расписание, можно (как и раньше) обратиться к представлению словаря данных DBA_SCHED- ULER_JOBS. Предположим, что задание TABSTAT_SAVINGS создано заново с использованием именованного расписания. Два других задания все еще сопоставлены календарным строкам.
Как видите, столбец SCHEDULE_TYPE отображает значение NAMED для задания, которому было сопоставлено именованное расписание. Для остальных заданий (продолжающих использовать календарные строки) в этом столбце выводится значение CALENDAR. Столбец SCHEDULE_NAME содержит имя расписания, сопоставленного заданию. Кроме того, при сопоставлении заданию именованного расписания столбец REPEAT_IN- TERVAL для такого задания устанавливается в значение NULL.
< Предыдущая | Следующая > |
---|