Spec-Zone.ru › MySQL 9.2

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 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.

    Вы можете использовать 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.
https://docs.oracle.com/cd/E17952_01/mysql-9.2-en/create-event.html

Spec-Zone.ru

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