15.1.13 Оператор CREATE EVENT
CREATE
[DEFINER = user]
EVENT
[IF NOT EXISTS]
event_name
ON SCHEDULE schedule
[ON COMPLETION [NOT] PRESERVE]
[ENABLE | DISABLE | DISABLE ON {REPLICA | SLAVE}]
[COMMENT 'string']
DO event_body;
schedule: {
AT timestamp [+ INTERVAL interval] ...
| EVERY interval
[STARTS timestamp [+ INTERVAL interval] ...]
[ENDS timestamp [+ INTERVAL interval] ...]
}
interval:
quantity {YEAR | QUARTER | MONTH | DAY | HOUR | MINUTE |
WEEK | SECOND | YEAR_MONTH | DAY_HOUR | DAY_MINUTE |
DAY_SECOND | HOUR_MINUTE | HOUR_SECOND | MINUTE_SECOND}
Данный оператор создаёт и планирует новое событие. Событие не выполняется, если планировщик событий не активирован. Для получения информации о проверке статуса планировщика событий и его активации при необходимости, см. Раздел 27.5.2, «Настройка планировщика событий».
CREATE EVENT требует привилегии EVENT для схемы, в которой должно быть создано событие. Если присутствует фраза DEFINER, требуемые привилегии зависят от значения user, как описано в Разделе 27.7, «Управление доступом к хранимым объектам».
Минимальные требования к оператору CREATE
EVENT следующие:
Ключевые слова
CREATE EVENTплюс имя события, которое однозначно идентифицирует событие в схеме базы данных.Фраза
ON SCHEDULE, которая определяет, когда и как часто событие выполняется.Фраза
DO, которая содержит оператор SQL, который должен быть выполнен событием.
Вот пример минимального оператора CREATE
EVENT:
CREATE EVENT myevent
ON SCHEDULE AT CURRENT_TIMESTAMP + INTERVAL 1 HOUR
DO
UPDATE myschema.mytable SET mycol = mycol + 1;
Предыдущий оператор создаёт событие с именем myevent. Это событие выполняется один раз — через один час после своего создания — путём выполнения оператора SQL, который увеличивает значение столбца mycol таблицы myschema.mytable на 1.
event_name должно быть допустимым идентификатором MySQL с максимальной длиной 64 символа. Имена событий не чувствительны к регистру, поэтому у вас не может быть двух событий с именами myevent и MyEvent в одной схеме. В целом, правила, регулирующие имена событий, аналогичны правилам для имён хранимых процедур. См. Раздел 11.2, «Имена объектов схемы».
Событие ассоциировано со схемой. Если схема не указана как часть event_name, предполагается схема по умолчанию (текущая). Чтобы создать событие в определённой схеме, укажите имя события со схемой, используя синтаксис . schema_name.event_name
Фраза DEFINER указывает учётную запись MySQL, которая будет использоваться при проверке привилегий во время выполнения события. Если присутствует фраза DEFINER, значение user должно быть учётной записью MySQL, заданной как ', user_name'@'host_name'CURRENT_USER или CURRENT_USER(). Разрешённые значения user зависят от ваших привилегий, как описано в Разделе 27.7, «Управление доступом к хранимым объектам». Также см. этот раздел для получения дополнительной информации о безопасности событий.
Если фраза DEFINER опущена, задаваемым по умолчанию определенным является пользователь, который выполняет оператор CREATE
EVENT. Это то же самое, что явное указание DEFINER = CURRENT_USER.
Внутри тела события функция CURRENT_USER возвращает учётную запись, используемую для проверки привилегий во время выполнения события, которая является пользователем DEFINER. Для получения информации об аудировании пользователей в событиях см. Раздел 8.2.23, «Аудит активности учётных записей на основе SQL».
IF NOT EXISTS имеет такое же значение для CREATE EVENT, как и для CREATE TABLE: Если событие с именем event_name уже существует в той же схеме, никаких действий не выполняется, и не возникает ошибок. (Однако в таких случаях генерируется предупреждение.)
Фраза ON SCHEDULE определяет, когда, как часто и на какой срок повторяется действие event_body, определённое для события. Эта фраза принимает одну из двух форм:
-
ATиспользуется для одноразового события. Она указывает, что событие выполняется только один раз в заданную дату и время с помощьюtimestamptimestamp, которое должно включать дату и время или должно быть выражением, которое разрешается в значение datetime. Для этой цели вы можете использовать значение типаDATETIMEилиTIMESTAMP. Если дата находится в прошлом, возникает предупреждение, как показано здесь:mysql>
SELECT NOW();+---------------------+ | NOW() | +---------------------+ | 2006-02-10 23:59:01 | +---------------------+ 1 row in set (0.04 sec) mysql>CREATE EVENT e_totals->ON SCHEDULE AT '2006-02-10 23:59:00'->DO INSERT INTO test.totals VALUES (NOW());Query OK, 0 rows affected, 1 warning (0.00 sec) mysql>SHOW WARNINGS\G*************************** 1. row *************************** Level: Note Code: 1588 Message: Event execution time is in the past and ON COMPLETION NOT PRESERVE is set. The event was dropped immediately after creation.Операторы
CREATE EVENT, которые сами по себе некорректны — по какой-либо причине — завершаются с ошибкой.Для указания текущей даты и времени можно использовать
CURRENT_TIMESTAMP. В таком случае событие выполняется сразу после создания.Чтобы создать событие, которое происходит в какой-то момент в будущем относительно текущей даты и времени, например, то, что выражается фразой «через три недели», можно использовать необязательную фразу
+ INTERVAL. Частьintervalintervalсостоит из двух частей: величины и единицы времени и следует правилам синтаксиса, описанным в Временных интервалах, за исключением того, что вы не можете использовать ключевые слова единиц, которые включают микросекунды, при определении события. С некоторыми типами интервалов можно использовать сложные единицы времени. Например, «две минуты и десять секунд» можно выразить как+ INTERVAL '2:10' MINUTE_SECOND.Вы также можете объединять интервалы. Например,
AT CURRENT_TIMESTAMP + INTERVAL 3 WEEK + INTERVAL 2 DAYэквивалентно «через три недели и два дня». Каждая часть такой фразы должна начинаться с+ INTERVAL. -
Для повторения действий через равные промежутки времени используйте фразу
EVERY. Ключевое словоEVERYследует заinterval, как описано в предыдущем обсуждении ключевого словаAT. (+ INTERVALне используется сEVERY). Например,EVERY 6 WEEKозначает «каждые шесть недель».Хотя фразы
+ INTERVALне допускаются в фразеEVERY, вы можете использовать те же сложные единицы времени, которые допускаются в+ INTERVAL.Фраза
EVERYможет содержать необязательную фразуSTARTS.STARTSследует за значениемtimestamp, которое указывает, когда действие должно начать повторяться, и также может использовать+ INTERVALдля указания временного интервала «от текущего времени». Например,intervalEVERY 3 MONTH STARTS CURRENT_TIMESTAMP + INTERVAL 1 WEEKозначает «каждые три месяца, начиная с одной недели от текущей». Аналогично, вы можете выразить «каждые две недели, начиная с шести часов и пятнадцати минут от текущего времени» какEVERY 2 WEEK STARTS CURRENT_TIMESTAMP + INTERVAL '6:15' HOUR_MINUTE. ОтсутствиеSTARTSто же самое, что использованиеSTARTS CURRENT_TIMESTAMP— то есть, действие, указанное для события, начинает повторяться сразу после создания события.Фраза
EVERYможет содержать необязательную фразуENDS. Ключевое словоENDSследует за значениемtimestamp, которое сообщает MySQL, когда событие должно перестать повторяться. Вы также можете использовать+ INTERVALсintervalENDS; например,EVERY 12 HOUR STARTS CURRENT_TIMESTAMP + INTERVAL 30 MINUTE ENDS CURRENT_TIMESTAMP + INTERVAL 4 WEEKэквивалентно «каждые двенадцать часов, начиная с тридцати минут от текущего времени и заканчивая четырьмя неделями от текущего». ОтсутствиеENDSозначает, что событие продолжает выполняться неограниченно.ENDSподдерживает тот же синтаксис для сложных единиц времени, что иSTARTS.Вы можете использовать
STARTS,ENDS, оба или ни одного из них в фразеEVERY.Фраза
ON SCHEDULEможет использовать выражения, включающие встроенные функции MySQL и пользовательские переменные, чтобы получить любое из значенийtimestampилиinterval, которые она содержит. Вы не можете использовать хранимые функции или загружаемые функции в таких выражениях, а также не можете использовать какие-либо ссылки на таблицы; однако вы можете использоватьSELECT FROM DUAL. Это верно как для операторовCREATE EVENT, так и для операторовALTER EVENT. Ссылки на хранимые функции, загружаемые функции и таблицы в таких случаях запрещены и завершаются ошибкой (см. ошибку #22830).
Временные значения в пункте ON SCHEDULE интерпретируются с использованием текущего значения переменной сессии time_zone. Это становится часовым поясом события; то есть, часовым поясом, который используется для планирования событий и действует в рамках события во время его выполнения. Эти временные значения преобразуются в UTC и сохраняются вместе с часовым поясом события внутри. Это позволяет событию выполняться так, как определено, независимо от любых последующих изменений часового пояса сервера или эффектов летнего времени. Дополнительную информацию о представлении временных значений событий см. в разделе 27.5.4 «Метаданные событий». См. также раздел 15.7.7.20 «Запрос SHOW EVENTS» и раздел 28.3.14 «Таблица INFORMATION_SCHEMA EVENTS».
Обычно, после истечения срока действия события, оно немедленно удаляется. Вы можете изменить это поведение, указав ON
COMPLETION PRESERVE. Использование ON COMPLETION NOT
PRESERVE просто делает явным поведение по умолчанию – не сохранять.
Вы можете создать событие, но предотвратить его активацию, используя ключевое слово DISABLE. В качестве альтернативы, вы можете использовать ENABLE, чтобы сделать явным состояние по умолчанию, которое является активным. Это наиболее полезно в сочетании с ALTER EVENT (см. раздел 15.1.3 «Команда ALTER EVENT»).
Третье значение также может появиться вместо ENABLE или DISABLE; DISABLE ON REPLICA устанавливается для статуса события на реплике, чтобы указать, что событие было создано на сервере источника репликации и реплицировано на реплику, но не выполняется на реплике. См. раздел 19.5.1.16 «Репликация вызываемых функций».
DISABLE ON REPLICA заменяет DISABLE ON
SLAVE, которое устарело и, следовательно, может быть удалено в будущих версиях MySQL.
Вы можете добавить комментарий к событию, используя пункт COMMENT. comment может быть любой строкой длиной до 64 символов, которую вы хотите использовать для описания события. Текст комментария, являясь строковой литеральной константой, должен быть заключен в кавычки.
Пункт DO определяет действие, выполняемое событием, и состоит из оператора SQL. Практически любой допустимый оператор MySQL, который может быть использован в хранимой процедуре, также может использоваться в качестве оператора действия для запланированного события. (См. раздел 27.9 «Ограничения на хранимые программы».) Например, следующее событие e_hourly удаляет все строки из таблицы sessions один раз в час, где эта таблица является частью схемы site_activity:
CREATE EVENT e_hourly
ON SCHEDULE
EVERY 1 HOUR
COMMENT 'Clears out sessions table each hour.'
DO
DELETE FROM site_activity.sessions;
MySQL сохраняет значение системной переменной sql_mode, установленное в момент создания или изменения события, и всегда выполняет событие с этим значением, независимо от текущего режима SQL сервера во время начала выполнения события.
Оператор CREATE EVENT, содержащий оператор ALTER EVENT в своем пункте DO, кажется успешным; однако, когда сервер пытается выполнить полученное запланированное событие, выполнение завершается ошибкой.
Операторы, такие как SELECT или SHOW, которые просто возвращают набор результатов, не имеют эффекта при использовании в событии; вывод из них не отправляется в монитор MySQL и не хранится нигде. Однако вы можете использовать операторы, такие как SELECT ...
INTO и INSERT INTO ...
SELECT, которые сохраняют результат. (См. следующий пример в этом разделе для примера последнего.)
Схема, к которой принадлежит событие, является схемой по умолчанию для ссылок на таблицы в пункте DO. Все ссылки на таблицы в других схемах должны быть квалифицированы соответствующим именем схемы.
Как и в хранимых процедурах, вы можете использовать синтаксис составных операторов в пункте DO, используя ключевые слова BEGIN и END, как показано здесь:
delimiter |
CREATE EVENT e_daily
ON SCHEDULE
EVERY 1 DAY
COMMENT 'Saves total number of sessions then clears the table each day'
DO
BEGIN
INSERT INTO site_activity.totals (time, total)
SELECT CURRENT_TIMESTAMP, COUNT(*)
FROM site_activity.sessions;
DELETE FROM site_activity.sessions;
END |
delimiter ;
В этом примере используется команда delimiter для изменения разделителя операторов. См. раздел 27.1 «Определение хранимых программ».
Более сложные составные операторы, такие как те, которые используются в хранимых процедурах, возможны в событии. Этот пример использует локальные переменные, обработчик ошибок и конструкцию управления потоком:
delimiter |
CREATE EVENT e
ON SCHEDULE
EVERY 5 SECOND
DO
BEGIN
DECLARE v INTEGER;
DECLARE CONTINUE HANDLER FOR SQLEXCEPTION BEGIN END;
SET v = 0;
WHILE v < 5 DO
INSERT INTO t1 VALUES (0);
UPDATE t2 SET s1 = s1 + 1;
SET v = v + 1;
END WHILE;
END |
delimiter ;
Нет возможности передавать параметры напрямую в события или из них; однако, возможно вызвать хранимую процедуру с параметрами внутри события:
CREATE EVENT e_call_myproc
ON SCHEDULE
AT CURRENT_TIMESTAMP + INTERVAL 1 DAY
DO CALL myproc(5, 27);
В MySQL 9.2 оператор CREATE EVENT может быть подготовлен, но текст оператора не должен содержать каких-либо заполнителей (?). Один из способов обойти это ограничение – собрать текст оператора, подготовить его и выполнить его внутри хранимой процедуры; переменные части оператора CREATE EVENT могут быть переданы в хранимую процедуру в качестве параметров. Мы демонстрируем это в следующем примере, который предполагает, что уже существует таблица t в базе данных d, созданная как показано здесь:
USE d;
CREATE TABLE t (
c1 INT NOT NULL AUTO_INCREMENT PRIMARY KEY,
c2 VARCHAR(20),
c3 INT
);
Мы хотим создать событие, которое вставляет строки в эту таблицу с интервалами, определяемыми во время создания, подобно событию, определённому оператором, показанным здесь:
CREATE EVENT e
ON SCHEDULE EVERY interval SECOND
STARTS CURRENT_TIMESTAMP + INTERVAL 10 SECOND
ENDS CURRENT_TIMESTAMP + INTERVAL 2 MINUTE
ON COMPLETION PRESERVE
DO
INSERT INTO d.t1 VALUES ROW(NULL, NOW(), FLOOR(RAND()*100));
Мы не можем использовать ? в качестве заполнителя для interval, но можем передать значение параметра в хранимую процедуру, как это показано здесь:
delimiter |
CREATE PROCEDURE sp(n INT)
BEGIN
SET @s1 = "CREATE EVENT e ON SCHEDULE EVERY ";
SET @s2 = " SECOND
STARTS CURRENT_TIMESTAMP + INTERVAL 10 SECOND
ENDS CURRENT_TIMESTAMP + INTERVAL 2 MINUTE
ON COMPLETION PRESERVE
DO
INSERT INTO d.t VALUES ROW(NULL, NOW(), FLOOR(RAND()*100))";
SET @s = CONCAT(@s1, n, @s2);
PREPARE ps FROM @s;
EXECUTE ps;
DEALLOCATE PREPARE ps;
END |
delimiter ;
mysql> TABLE t;
Empty set (0.00 sec)
mysql> CALL sp(5);
Query OK, 0 rows affected (0.01 sec)
# Wait 2 minutes...
mysql> TABLE t;
+----+---------------------+------+
| c1 | c2 | c3 |
+----+---------------------+------+
| 1 | 2024-06-12 15:53:36 | 41 |
| 2 | 2024-06-12 15:53:41 | 84 |
| 3 | 2024-06-12 15:53:46 | 71 |
| 4 | 2024-06-12 15:53:51 | 78 |
| 5 | 2024-06-12 15:53:56 | 53 |
| 6 | 2024-06-12 15:54:01 | 6 |
| 7 | 2024-06-12 15:54:06 | 48 |
| 8 | 2024-06-12 15:54:11 | 98 |
| 9 | 2024-06-12 15:54:16 | 22 |
| 10 | 2024-06-12 15:54:21 | 88 |
| 11 | 2024-06-12 15:54:26 | 53 |
| 12 | 2024-06-12 15:54:31 | 75 |
| 13 | 2024-06-12 15:54:36 | 93 |
| 14 | 2024-06-12 15:54:41 | 13 |
| 15 | 2024-06-12 15:54:46 | 62 |
| 16 | 2024-06-12 15:54:51 | 47 |
| 17 | 2024-06-12 15:54:56 | 22 |
| 18 | 2024-06-12 15:55:01 | 47 |
| 19 | 2024-06-12 15:55:06 | 43 |
| 20 | 2024-06-12 15:55:11 | 50 |
| 21 | 2024-06-12 15:55:16 | 98 |
| 22 | 2024-06-12 15:55:21 | 15 |
| 23 | 2024-06-12 15:55:26 | 56 |
+----+---------------------+------+
23 rows in set (0.00 sec)
После вызова sp со значением аргумента 5, как показано, и ожидания 2 минут до завершения выполнения события e, мы можем увидеть, что таблица t обновлялась каждые 5 секунд. Так как e был создан с ON COMPLETION
PRESERVE, мы можем увидеть его в таблице Информационной Схемы EVENTS и проверить, что он был создан как ожидалось:
mysql> SELECT EVENT_NAME, EVENT_SCHEMA, EVENT_DEFINITION, EVENT_TYPE
> FROM INFORMATION_SCHEMA.EVENTS WHERE EVENT_NAME='e'\G
*************************** 1. row ***************************
EVENT_NAME: e
EVENT_SCHEMA: d
EVENT_DEFINITION: INSERT INTO d.t VALUES ROW(NULL, NOW(), FLOOR(RAND()*100))
EVENT_TYPE: RECURRING
1 row in set (0.00 sec)
Если у определяющего событие пользователя есть права для установки глобальных системных переменных (см. раздел 7.1.9.1 «Права на системные переменные»), событие может читать и записывать глобальные переменные. Поскольку предоставление таких привилегий влечёт за собой потенциальную возможность злоупотребления, необходимо проявлять особую осторожность при их предоставлении.
В целом, любые операторы, допустимые в хранимых процедурах, могут использоваться для операторов действия, выполняемых событиями. Дополнительную информацию об операторах, разрешенных в хранимых процедурах, см. в разделе 27.2.1 «Синтаксис хранимых процедур». Невозможно создать событие в рамках хранимой процедуры или создать событие другим событием.
© 2025 Oracle
Licensed under the GPLv2 License.