Spec-Zone.ru › MySQL 8.4

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.4.2, «Настройка планировщика событий».

CREATE EVENT требует EVENT привилегии для схемы, в которой должно быть создано событие. Если присутствует фрагмент DEFINER, необходимые привилегии зависят от значения user, как описано в Разделе 27.6, «Управление доступом к хранимым объектам».

Минимальные требования для допустимого оператора 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.6, «Управление доступом к хранимым объектам». Также в этом разделе содержится дополнительная информация о безопасности событий.

Если фрагмент 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 timestamp используется для одноразового события. Он указывает, что событие выполняется только один раз в заданную дату и время, указанное в timestamp, которое должно включать как дату, так и время, или должно быть выражением, которое преобразуется в значение 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 interval. Часть interval состоит из двух частей: количества и единицы времени и следует правилам синтаксиса, описанным в Интервалах времени, за исключением того, что нельзя использовать никакие ключевые слова единиц, включающих микросекунды, при определении события. Для некоторых типов интервалов могут использоваться сложные единицы времени. Например, «через две минуты и десять секунд» можно записать как + 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 interval для указания отрезка времени «с этого момента». Например, EVERY 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 interval с ENDS; например, EVERY 12 HOUR STARTS CURRENT_TIMESTAMP + INTERVAL 30 MINUTE ENDS CURRENT_TIMESTAMP + INTERVAL 4 WEEK эквивалентно «каждые двенадцать часов, начиная с тридцати минут с этого момента, и заканчивая через четыре недели». Отсутствие фрагмента ENDS означает, что событие выполняется неограниченно.

    ENDS поддерживает тот же синтаксис для сложных единиц времени, что и STARTS.

    В фрагменте EVERY можно использовать STARTS, ENDS, оба, или ни одного.

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

Фрагмент ON SCHEDULE может использовать выражения, включающие встроенные функции MySQL и переменные пользователя, для получения любого из значений timestamp или interval, которые он содержит. В таких выражениях нельзя использовать хранимые или загружаемые функции, а также ссылки на таблицы; однако можно использовать SELECT FROM DUAL. Это относится как к операторам CREATE EVENT, так и ALTER EVENT. Ссылки на хранимые функции, загружаемые функции и таблицы в таких случаях запрещены и завершаются ошибкой (см. баг #22830).

Временные значения в пункте ON SCHEDULE интерпретируются с использованием текущего значения переменной сессии time_zone. Это становится часовым поясом события; то есть, часовым поясом, используемым для планирования событий и действующим в рамках события при его выполнении. Эти временные значения преобразуются в UTC и сохраняются вместе с часовым поясом события внутри. Это позволяет выполнению события проходить согласно определению независимо от любых последующих изменений часового пояса сервера или эффектов перехода на летнее время. Дополнительную информацию о представлении временных значений событий см. в разделе 27.4.4, «Метаданные событий». См. также раздел 15.7.7.19, «Запрос SHOW EVENTS» и раздел 28.3.14, «Таблица INFORMATION_SCHEMA EVENTS».

Обычно, после истечения срока действия события, оно немедленно удаляется. Вы можете изменить это поведение, указав ON COMPLETION PRESERVE. Использование ON COMPLETION NOT PRESERVE просто делает явным поведение по умолчанию, не сохраняющее состояние.

Вы можете создать событие, но предотвратить его активацию, используя ключевое слово DISABLE. В качестве альтернативы, вы можете использовать ENABLE, чтобы сделать явным состояние по умолчанию, которое является активным. Это наиболее полезно в сочетании с ALTER EVENT (см. раздел 15.1.3, «Управление событием»).

Третье значение также может появиться вместо ENABLE или DISABLE; DISABLE ON REPLICA устанавливается для состояния события на реплике, чтобы указать, что событие было создано на сервере репликации и реплицировано на реплику, но не выполняется на реплике. См. раздел 19.5.1.16, «Репликация вызываемых функций».

DISABLE ON REPLICA заменяет DISABLE ON SLAVE, которое устарело и, следовательно, может быть удалено в будущей версии MySQL.

Вы можете добавить комментарий к событию, используя пункт COMMENT. comment может быть любой строкой длиной до 64 символов, которую вы хотите использовать для описания события. Текст комментария, являясь строковым литералом, должен быть заключен в кавычки.

Пункт DO определяет действие, выполняемое событием, и состоит из SQL-запроса. Почти любой допустимый MySQL-запрос, который можно использовать в хранимой процедуре, также может быть использован в качестве запроса действия для запланированного события. (См. раздел 27.8, «Ограничения хранимых программ».) Например, следующее событие 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);

Если у определяющего событие есть права, достаточные для установки глобальных системных переменных (см. раздел 7.1.9.1, «Права на системные переменные»), событие может читать и записывать глобальные переменные. Поскольку предоставление таких прав влечёт потенциальную возможность злоупотребления, необходимо проявить особую осторожность при этом.

В целом, любые операторы, допустимые в хранимых процедурах, могут быть использованы для операторов действия, выполняемых событиями. Дополнительную информацию об операторах, допустимых в хранимых процедурах, см. в разделе 27.2.1, «Синтаксис хранимых процедур». Невозможно создать событие как часть хранимой процедуры или создать событие с помощью другого события.

© 2025 Oracle
Licensed under the GPLv2 License.
https://docs.oracle.com/cd/E17952_01/mysql-8.4-en/create-event.html

Spec-Zone.ru

Настройки Оффлайн Что нового Помощь О нас
Spec-Zone .ru
спецификации, руководства, описания, API