文档首页
MySQL 8.4 参考手册
8.4 中文镜像

MySQL 8.4 参考手册 · 中文镜像

正文为中文,英文原文默认隐藏。点击任意中文段落即可展开 / 收起对应英文原文。

打开官方英文原文 ↗

译文由机器翻译生成,仅供理解参考;有疑问请以官方英文原文为准。

中文点击中文段落可显示 / 隐藏英文原文本页译文覆盖 100%

15.1.13 CREATE EVENT 语句15.1.13 CREATE EVENT Statement

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 节,“事件调度器配置”。This statement creates and schedules a new event. The event does not run unless the Event Scheduler is enabled. For information about checking Event Scheduler status and enabling it if necessary, see Section 27.4.2, “Event Scheduler Configuration”.

CREATE EVENT 需要在要创建事件的模式中具有 EVENT 权限。如果存在 DEFINER 子句,则所需权限取决于 user 值,如 第 27.6 节,“存储对象访问控制” 中所述。CREATE EVENT requires the EVENT privilege for the schema in which the event is to be created. If the DEFINER clause is present, the privileges required depend on the user value, as discussed in Section 27.6, “Stored Object Access Control”.

有效 CREATE EVENT 语句的最低要求如下:The minimum requirements for a valid CREATE EVENT statement are as follows:

  • 关键字 CREATE EVENT 以及一个事件名称,用于在数据库模式中唯一标识该事件。The keywords CREATE EVENT plus an event name, which uniquely identifies the event in a database schema.

  • ON SCHEDULE 子句,用于确定事件何时以及多频率执行。An ON SCHEDULE clause, which determines when and how often the event executes.

  • 一个 DO 子句,其中包含事件要执行的 SQL 语句。A DO clause, which contains the SQL statement to be executed by an event.

这是一个最小 CREATE EVENT 语句的示例:This is an example of a minimal CREATE EVENT statement:

CREATE EVENT myevent
    ON SCHEDULE AT CURRENT_TIMESTAMP + INTERVAL 1 HOUR
    DO
      UPDATE myschema.mytable SET mycol = mycol + 1;

前面的语句创建了一个名为 myevent 的事件。此事件会在创建后一小时执行一次,通过运行 SQL 语句将 myschema.mytable 表的 mycol 列的值加 1。The previous statement creates an event named myevent. This event executes once—one hour following its creation—by running an SQL statement that increments the value of the myschema.mytable table's mycol column by 1.

event_name 必须是有效的 MySQL 标识符,最大长度为 64 个字符。事件名称不区分大小写,因此在同一模式中不能有两个事件分别命名为 myevent 和 MyEvent。通常,事件名称的规则与存储例程名称相同。参见 第 11.2 节,“模式对象名称”。The event_name must be a valid MySQL identifier with a maximum length of 64 characters. Event names are not case-sensitive, so you cannot have two events named myevent and MyEvent in the same schema. In general, the rules governing event names are the same as those for names of stored routines. See Section 11.2, “Schema Object Names”.

事件与模式关联。如果 event_name 中未指明任何模式,则假定为默认(当前)模式。要在特定模式中创建事件,请使用 schema_name.event_name 语法为事件名称加上模式限定符。An event is associated with a schema. If no schema is indicated as part of event_name, the default (current) schema is assumed. To create an event in a specific schema, qualify the event name with a schema using schema_name.event_name syntax.

DEFINER 子句指定在事件执行时检查访问权限所使用的 MySQL 帐号。如果存在 DEFINER 子句,user 值应为 MySQL 帐号,格式为 'user_name'@'host_name'、CURRENT_USER 或 CURRENT_USER()。允许的 user 值取决于您拥有的权限,如 第 27.6 节,“存储对象访问控制” 中所讨论的内容。有关事件安全的更多信息,也请参见该节。The DEFINER clause specifies the MySQL account to be used when checking access privileges at event execution time. If the DEFINER clause is present, the user value should be a MySQL account specified as 'user_name'@'host_name', CURRENT_USER, or CURRENT_USER(). The permitted user values depend on the privileges you hold, as discussed in Section 27.6, “Stored Object Access Control”. Also see that section for additional information about event security.

如果省略 DEFINER 子句,则默认的定义者为执行 CREATE EVENT 语句的用户。这与显式指定 DEFINER = CURRENT_USER 相同。If the DEFINER clause is omitted, the default definer is the user who executes the CREATE EVENT statement. This is the same as specifying DEFINER = CURRENT_USER explicitly.

在事件体内,CURRENT_USER 函数返回在事件执行时用于检查权限的账户,即 DEFINER 用户。有关事件中用户审计的信息,请参见 第 8.2.23 节,“基于 SQL 的账户活动审计”。Within an event body, the CURRENT_USER function returns the account used to check privileges at event execution time, which is the DEFINER user. For information about user auditing within events, see Section 8.2.23, “SQL-Based Account Activity Auditing”.

IF NOT EXISTS 对 CREATE EVENT 的含义与对 CREATE TABLE 的含义相同:如果同一模式中已经存在名为 event_name 的事件,则不执行任何操作,也不会产生错误。(但是,在这种情况下会生成警告。)IF NOT EXISTS has the same meaning for CREATE EVENT as for CREATE TABLE: If an event named event_name already exists in the same schema, no action is taken, and no error results. (However, a warning is generated in such cases.)

ON SCHEDULE 子句确定事件定义的 event_body 何时、多久以及重复的频率。这个子句有两种形式:The ON SCHEDULE clause determines when, how often, and for how long the event_body defined for the event repeats. This clause takes one of two forms:

  • AT timestamp 用于一次性事件。它指定事件仅在 timestamp 给定的日期和时间执行一次,该值必须包含日期和时间,或者必须是解析为日期时间值的表达式。您可以使用 DATETIME 或 TIMESTAMP 类型的值。如果日期是过去的时间,则会产生警告,如下所示:AT timestamp is used for a one-time event. It specifies that the event executes one time only at the date and time given by timestamp, which must include both the date and time, or must be an expression that resolves to a datetime value. You may use a value of either the DATETIME or TIMESTAMP type for this purpose. If the date is in the past, a warning occurs, as shown here:

    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 语句本身如果因任何原因无效,将以错误结束。CREATE EVENT statements which are themselves invalid—for whatever reason—fail with an error.

    您可以使用 CURRENT_TIMESTAMP 来指定当前日期和时间。在这种情况下,事件会在创建时立即执行。You may use CURRENT_TIMESTAMP to specify the current date and time. In such a case, the event acts as soon as it is created.

    要创建一个在相对于当前日期和时间的未来某个时间发生的事件,例如用短语 “三周后” 表示的时间,您可以使用可选的子句 + INTERVAL interval。interval 部分由两个部分组成:数量和时间单位,并遵循 时间间隔 中描述的语法规则,只是定义事件时不能使用涉及微秒的单位关键字。对于某些间隔类型,可以使用复杂的时间单位。例如,“两分钟十秒” 可以表示为 + INTERVAL '2:10' MINUTE_SECOND。To create an event which occurs at some point in the future relative to the current date and time—such as that expressed by the phrase “three weeks from now”—you can use the optional clause + INTERVAL interval. The interval portion consists of two parts, a quantity and a unit of time, and follows the syntax rules described in Temporal Intervals, except that you cannot use any units keywords that involving microseconds when defining an event. With some interval types, complex time units may be used. For example, “two minutes and ten seconds” can be expressed as + INTERVAL '2:10' MINUTE_SECOND.

    您也可以组合间隔。例如,AT CURRENT_TIMESTAMP + INTERVAL 3 WEEK + INTERVAL 2 DAY 相当于 “三周零两天后”。这种子句的每一部分都必须以 + INTERVAL 开头。You can also combine intervals. For example, AT CURRENT_TIMESTAMP + INTERVAL 3 WEEK + INTERVAL 2 DAY is equivalent to “three weeks and two days from now”. Each portion of such a clause must begin with + INTERVAL.

  • 要以固定间隔重复执行操作,请使用一个EVERY子句。关键字EVERY后跟一个interval如前文关于AT关键字的讨论中所述。+ INTERVAL is 在多线程系统中 used with EVERY与EVERY 6 WEEK一起使用)例如,“表示”.To repeat actions at a regular interval, use an EVERY clause. The EVERY keyword is followed by an interval as described in the previous discussion of the AT keyword. (+ INTERVAL is not used with EVERY.) For example, EVERY 6 WEEK means “every six weeks”.

    虽然 + INTERVAL 子句在 EVERY 子句中不允许,但您可以使用 + INTERVAL 中允许的相同复杂时间单位。Although + INTERVAL clauses are not permitted in an EVERY clause, you can use the same complex time units permitted in a + INTERVAL.

    每六周EVERY一个STARTS子句创建的表空间。STARTS从句可能包含一个可选的timestamp后跟一个+ INTERVAL interval值,用于指示操作应何时开始重复,并且还可以使用“来指定从现在起的时间量”例如,EVERY 3 MONTH STARTS CURRENT_TIMESTAMP + INTERVAL 1 WEEK一起使用)例如,“每三个月一次,从现在起一周开始”. Similarly, you can express “every two weeks, beginning six hours and fifteen minutes from now” as EVERY 2 WEEK STARTS CURRENT_TIMESTAMP + INTERVAL '6:15' HOUR_MINUTE. Not specifying STARTS is the same as using STARTS CURRENT_TIMESTAMP—that is, the action specified for the event begins repeating immediately upon creation of the event.An EVERY clause may contain an optional STARTS clause. STARTS is followed by a timestamp value that indicates when the action should begin repeating, and may also use + INTERVAL interval to specify an amount of time “from now”. For example, EVERY 3 MONTH STARTS CURRENT_TIMESTAMP + INTERVAL 1 WEEK means “every three months, beginning one week from now”. Similarly, you can express “every two weeks, beginning six hours and fifteen minutes from now” as EVERY 2 WEEK STARTS CURRENT_TIMESTAMP + INTERVAL '6:15' HOUR_MINUTE. Not specifying STARTS is the same as using STARTS CURRENT_TIMESTAMP—that is, the action specified for the event begins repeating immediately upon creation of the event.

    每个 EVERY 子句可以包含一个可选的 ENDS 子句。ENDS 关键字后跟一个 timestamp 值,用于告诉 MySQL 事件何时停止重复。您还可以在 ENDS 中使用 + INTERVAL interval;例如,EVERY 12 HOUR STARTS CURRENT_TIMESTAMP + INTERVAL 30 MINUTE ENDS CURRENT_TIMESTAMP + INTERVAL 4 WEEK 等同于 “每十二小时一次,从现在起三十分钟开始,四周后结束””。不使用 ENDS 意味着事件会无限期执行。An EVERY clause may contain an optional ENDS clause. The ENDS keyword is followed by a timestamp value that tells MySQL when the event should stop repeating. You may also use + INTERVAL interval with ENDS; for instance, EVERY 12 HOUR STARTS CURRENT_TIMESTAMP + INTERVAL 30 MINUTE ENDS CURRENT_TIMESTAMP + INTERVAL 4 WEEK is equivalent to “every twelve hours, beginning thirty minutes from now, and ending four weeks from now”. Not using ENDS means that the event continues executing indefinitely.

    ENDS 支持与 STARTS 相同的复杂时间单位语法。ENDS supports the same syntax for complex time units as STARTS does.

    您可以在 EVERY 子句中使用 STARTS、ENDS、两者或都不使用。You may use STARTS, ENDS, both, or neither in an EVERY clause.

    如果重复事件在其调度间隔内未终止,可能导致事件的多个实例同时执行。如果这是不希望的,您应建立机制防止同时执行实例。例如,您可以使用 GET_LOCK() 函数,或行锁或表锁。If a repeating event does not terminate within its scheduling interval, the result may be multiple instances of the event executing simultaneously. If this is undesirable, you should institute a mechanism to prevent simultaneous instances. For example, you could use the GET_LOCK() function, or row or table locking.

ON SCHEDULE 子句可以使用包含内置 MySQL 函数和用户变量的表达式来获取其中的任何 timestamp 或 interval 值。在这些表达式中不得使用存储函数或可加载函数,也不得引用任何表;但是,可以使用 SELECT FROM DUAL。这对于 CREATE EVENT 和 ALTER EVENT 语句都适用。在这些情况下,特别禁止引用存储函数、可加载函数和表,否则会出错(参见 Bug #22830)。The ON SCHEDULE clause may use expressions involving built-in MySQL functions and user variables to obtain any of the timestamp or interval values which it contains. You may not use stored functions or loadable functions in such expressions, nor may you use any table references; however, you may use SELECT FROM DUAL. This is true for both CREATE EVENT and ALTER EVENT statements. References to stored functions, loadable functions, and tables in such cases are specifically not permitted, and fail with an error (see Bug #22830).

ON SCHEDULE 子句中的时间使用当前会话的 time_zone 值解释。这成为事件的时区;即用于事件调度并在事件执行时生效的时区。这些时间会转换为 UTC 并与事件时区一同存储。这样无论服务器时区或夏令时后续如何变化,事件执行都可以按定义进行。有关事件时间表示的更多信息,请参见 第 27.4.4 节,“事件元数据”。另请参见 第 15.7.7.19 节,“SHOW EVENTS 语句” 和 第 28.3.14 节,“INFORMATION_SCHEMA EVENTS 表”。Times in the ON SCHEDULE clause are interpreted using the current session time_zone value. This becomes the event time zone; that is, the time zone that is used for event scheduling and is in effect within the event as it executes. These times are converted to UTC and stored along with the event time zone internally. This enables event execution to proceed as defined regardless of any subsequent changes to the server time zone or daylight saving time effects. For additional information about representation of event times, see Section 27.4.4, “Event Metadata”. See also Section 15.7.7.19, “SHOW EVENTS Statement”, and Section 28.3.14, “The INFORMATION_SCHEMA EVENTS Table”.

通常,事件一旦过期,它会立即被丢弃。你可以通过指定 ON COMPLETION PRESERVE。使用 ON COMPLETION NOT PRESERVE 只是让默认的非持久行为显式化。Normally, once an event has expired, it is immediately dropped. You can override this behavior by specifying ON COMPLETION PRESERVE. Using ON COMPLETION NOT PRESERVE merely makes the default nonpersistent behavior explicit.

你可以创建事件但阻止其激活,方法是 DISABLE 关键字。或者,你也可以使用 ENABLE,将默认状态显式化为活跃状态。这与 ALTER EVENT“(参见 第 15.1.3 节,”ALTER EVENT Statement“)。You can create an event but prevent it from being active using the DISABLE keyword. Alternatively, you can use ENABLE to make explicit the default status, which is active. This is most useful in conjunction with ALTER EVENT (see Section 15.1.3, “ALTER EVENT Statement”).

第三个值也可以替代 ENABLE 或 DISABLEDISABLE ON REPLICA REPLICA 设置为副本事件状态,表示该事件是在复制源服务器创建并复制到副本,但未在副本上执行。参见 第 19.5.1.16 节,“调用特征的复制”。A third value may also appear in place of ENABLE or DISABLE; DISABLE ON REPLICA is set for the status of an event on a replica to indicate that the event was created on the replication source server and replicated to the replica, but is not executed on the replica. See Section 19.5.1.16, “Replication of Invoked Features”.

DISABLE ON REPLICA REPLICA 取代了 DISABLE ON SLAVE后者已被弃用,因此未来版本的 MySQL 可能会被移除。DISABLE ON REPLICA replaces DISABLE ON SLAVE, which is deprecated, and thus subject to removal in a future version of MySQL.

您可以使用 COMMENT。comment 可以是您希望使用最多 64 字符的字符串来描述事件。注释文本作为字符串文字,必须被引号包围。You may supply a comment for an event using a COMMENT clause. comment may be any string of up to 64 characters that you wish to use for describing the event. The comment text, being a string literal, must be surrounded by quotation marks.

DO 子句指定事件所执行的动作,包含一个 SQL 语句。几乎任何可在存储例程中使用的有效 MySQL 语句,也可以用作调度事件的动作语句。(参见 第 27.8 节,“对存储程序的限制”。)例如,以下事件 e_hourly 每小时删除 sessions,该表属于 site_activity schema:The DO clause specifies an action carried by the event, and consists of an SQL statement. Nearly any valid MySQL statement that can be used in a stored routine can also be used as the action statement for a scheduled event. (See Section 27.8, “Restrictions on Stored Programs”.) For example, the following event e_hourly deletes all rows from the sessions table once per hour, where this table is part of the site_activity schema:

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 模式如何。MySQL stores the sql_mode system variable setting in effect when an event is created or altered, and always executes the event with this setting in force, regardless of the current server SQL mode when the event begins executing.

CREATE EVENT 语句,包含包含 ALTER EVENT statement in 其 DO 子句似乎成功;然而,当服务器尝试执行由此产生的定时事件时,执行会以错误告终。A CREATE EVENT statement that contains an ALTER EVENT statement in its DO clause appears to succeed; however, when the server attempts to execute the resulting scheduled event, the execution fails with an error.

Note

像 SELECT 或 SHOW 这样仅返回结果集的语句,在事件中使用时不会产生任何效果;这些语句的输出不会发送到 MySQL 监视器,也不会存储到任何地方。然而,你可以使用 SELECT ... INTO 和 INSERT INTO ... SELECT 这样可以存储结果的语句。(有关后者的示例,请参见本节的下一个示例。)Statements such as SELECT or SHOW that merely return a result set have no effect when used in an event; the output from these is not sent to the MySQL Monitor, nor is it stored anywhere. However, you can use statements such as SELECT ... INTO and INSERT INTO ... SELECT that store a result. (See the next example in this section for an instance of the latter.)

事件所属的模式是 DO 子句中表引用的默认模式。对其他模式中表的任何引用必须使用适当的模式名称进行限定。The schema to which an event belongs is the default schema for table references in the DO clause. Any references to tables in other schemas must be qualified with the proper schema name.

与存储例程一样,你可以在 DO 子句中使用复合语句语法,通过使用 BEGIN 和 END 关键字,如下所示:As with stored routines, you can use compound-statement syntax in the DO clause by using the BEGIN and END keywords, as shown here:

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 节,“定义存储程序”。This example uses the delimiter command to change the statement delimiter. See Section 27.1, “Defining Stored Programs”.

在事件中可以使用更复杂的复合语句,例如存储例程中使用的语句。此示例使用了局部变量、错误处理程序和流程控制构造:More complex compound statements, such as those used in stored routines, are possible in an event. This example uses local variables, an error handler, and a flow control construct:

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 ;

无法直接向事件传递参数或从事件接收参数;但是,可以在事件中调用带参数的存储例程:There is no way to pass parameters directly to or from events; however, it is possible to invoke a stored routine with parameters within an event:

CREATE EVENT e_call_myproc
    ON SCHEDULE
      AT CURRENT_TIMESTAMP + INTERVAL 1 DAY
    DO CALL myproc(5, 27);

如果事件的定义器拥有足够的权限来设置全局系统变量(参见 第 7.1.9.1 节,“系统变量特权”),事件可以读取和写入全局变量。由于授予此类权限存在滥用风险,使用时必须格外谨慎。If an event's definer has privileges sufficient to set global system variables (see Section 7.1.9.1, “System Variable Privileges”), the event can read and write global variables. As granting such privileges entails a potential for abuse, extreme care must be taken in doing so.

通常,任何在存储例程中有效的语句都可用于事件执行的动作语句。有关存储例程中允许语句的更多信息,请参见 第 27.2.1 节,“存储例程语法”。无法作为存储例程的一部分创建事件,也无法通过其他事件创建事件。Generally, any statements that are valid in stored routines may be used for action statements executed by events. For more information about statements permissible within stored routines, see Section 27.2.1, “Stored Routine Syntax”. It is not possible to create an event as part of a stored routine or to create an event by another event.