CREATE
[DEFINER = user]
EVENT
[IF NOT EXISTS]
event_name
ON SCHEDULE schedule
[ON COMPLETION [NOT] PRESERVE]
[ENABLE | DISABLE | DISABLE ON 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}此语句创建并安排新事件。除非启用事件计划程序,否则事件不会运行。有关检查 Event Scheduler 状态并在必要时启用它的信息,请参阅第 23.4.2 节,“Event Scheduler 配置”。
CREATE EVENT需要
EVENT在其中创建事件的模式的特权。如果
DEFINER存在该子句,所需的权限取决于user值,如第 23.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。myschema.mytable
此事件执行一次(在其创建后一小时),方法是运行一条将表列的值递增 1 的 SQL 语句mycol。
event_name必须是最大长度为 64 个字符的有效 MySQL 标识符
。事件名称不区分大小写,因此您不能
在同一架构中同时命名myevent和命名两个事件。MyEvent通常,管理事件名称的规则与存储例程名称的规则相同。请参阅
第 9.2 节,“模式对象名称”。
事件与架构相关联。如果没有模式被指示为 的一部分event_name,则假定默认(当前)模式。要在特定模式中创建事件,请使用
语法使用模式限定事件名称。
schema_name.event_name
该DEFINER子句指定在事件执行时检查访问权限时要使用的 MySQL 帐户。如果DEFINER存在该子句,则该
user值应该是指定为 、 或 的
MySQL
帐户
。允许的
值取决于您拥有的权限,如
第 23.6 节“存储对象访问控制”中所述。另请参阅该部分以获取有关事件安全性的其他信息。
'user_name'@'host_name'CURRENT_USERCURRENT_USER()user
如果DEFINER省略该子句,则默认定义者是执行该CREATE
EVENT语句的用户。这与明确指定相同
DEFINER = CURRENT_USER。
在事件主体中,该
CURRENT_USER函数返回用于在事件执行时检查权限的帐户,即DEFINER用户。有关事件中用户审计的信息,请参阅
第 6.2.18 节,“基于 SQL 的帐户活动审计”。
IF NOT EXISTSCREATE EVENTfor与 for
具有相同的含义
CREATE TABLE:如果名为的事件
event_name已存在于同一架构中,则不采取任何操作,也不会产生错误结果。(但是,在这种情况下会生成警告。)
该ON SCHEDULE子句确定event_body
为事件重复定义的时间、频率和时长。该子句采用以下两种形式之一:
AT用于一次性事件。它指定事件仅在 给定的日期和时间执行一次,该日期和时间timestamptimestamp必须包括日期和时间,或者必须是解析为日期时间值的表达式。为此,您可以使用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来指定当前日期和时间。在这种情况下,事件在创建后立即生效。要创建发生在相对于当前日期和时间的未来某个时间点的事件(例如短语“三周后”所表达的事件),您可以使用可选子句。该 部分由两部分组成,一个数量和一个时间单位,并遵循时间间隔中描述的语法规则,除了在定义事件时不能使用任何涉及微秒的单位关键字。对于某些间隔类型,可以使用复杂的时间单位。例如,“二分十秒”可以表示为。
+ INTERVALintervalinterval+ 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值,指示动作何时开始重复,也可以用来指定“从现在开始”的时间量。例如, 表示“每三个月,从现在开始一周”。同样,您可以将“每两周,从现在起六小时十五分钟开始”表示为。不指定 与使用相同+ INTERVALintervalEVERY 3 MONTH STARTS CURRENT_TIMESTAMP + INTERVAL 1 WEEKEVERY 2 WEEK STARTS CURRENT_TIMESTAMP + INTERVAL '6:15' HOUR_MINUTESTARTSSTARTS CURRENT_TIMESTAMP——也就是说,为事件指定的动作在事件创建后立即开始重复。一个
EVERY子句可以包含一个可选ENDS子句。ENDS关键字后跟一个值,该timestamp值告诉 MySQL 事件何时应该停止重复。你也可以使用with ; 例如,相当于 “每十二个小时,从现在开始三十分钟,从现在开始四个星期结束”。不使用 意味着事件将无限期地继续执行。+ INTERVALintervalENDSEVERY 12 HOUR STARTS CURRENT_TIMESTAMP + INTERVAL 30 MINUTE ENDS CURRENT_TIMESTAMP + INTERVAL 4 WEEKENDSENDS支持与复杂时间单位相同的语法STARTS。您可以在子句 中使用
STARTS,ENDS, both 或 neither 。EVERY如果重复事件没有在其调度间隔内终止,则结果可能是该事件的多个实例同时执行。如果这是不可取的,您应该建立一种机制来防止同时发生实例。例如,您可以使用
GET_LOCK()函数、行或表锁定。
该ON SCHEDULE子句可以使用涉及内置 MySQL 函数和用户变量的表达式来获取它包含的任何timestamp或
值。interval您不得在此类表达式中使用存储函数或可加载函数,也不得使用任何表引用;但是,您可以使用SELECT FROM DUAL. 对于
CREATE EVENTand
ALTER EVENT语句都是如此。在这种情况下,对存储函数、可加载函数和表的引用是明确不允许的,并且会因错误而失败(参见错误 #22830)。
ON SCHEDULE使用当前会话
time_zone值解释子句中的
时间。这成为事件时区;即,用于事件调度并在事件执行时在事件中生效的时区。这些时间将转换为 UTC 并与表中的事件时区一起存储mysql.event。这使事件执行能够按照定义继续进行,而不管服务器时区或夏令时的任何后续更改。有关事件时间表示的其他信息,请参阅第 23.4.4 节,“事件元数据”。另见
第 13.7.5.18 节,“SHOW EVENTS 语句”和
第 24.3.8 节,“INFORMATION_SCHEMA EVENTS 表”.
通常,一旦事件过期,它就会立即被删除。您可以通过指定覆盖此行为ON
COMPLETION PRESERVE。使用ON COMPLETION NOT
PRESERVE仅使默认的非持久行为显式化。
DISABLE您可以创建一个事件,但使用关键字
阻止它处于活动状态
。或者,您可以使用
ENABLE来明确默认状态,即活动状态。ALTER EVENT这与(请参阅
第 13.1.2 节,“ALTER EVENT 语句”)
结合使用时最有用
。
第三个值也可能出现在
ENABLEor的位置DISABLE;
DISABLE ON SLAVE为副本上的事件状态设置,以指示事件在源上创建并复制到副本,但不在副本上执行。请参阅第 16.4.1.16 节,“调用功能的复制”。
您可以使用
COMMENT子句为事件提供评论。
comment可以是您希望用于描述事件的最多 64 个字符的任何字符串。注释文本是字符串文字,必须用引号括起来。
子句指定事件携带的DO动作,由SQL语句组成。几乎任何可以在存储例程中使用的有效 MySQL 语句也可以用作计划事件的操作语句。(请参阅
第 23.8 节,“存储程序的限制”。)例如,以下事件每小时e_hourly从表中删除一次所有行,其中该表是模式的一部分:
sessionssite_activity
CREATE EVENT e_hourly
ON SCHEDULE
EVERY 1 HOUR
COMMENT 'Clears out sessions table each hour.'
DO
DELETE FROM site_activity.sessions;
MySQLsql_mode在创建或更改事件时存储有效的系统变量设置,并且始终使用此设置执行事件,
而不管事件开始执行时当前服务器 SQL 模式如何。
在其子句CREATE EVENT中包含语句
的语句似乎成功;但是,当服务器尝试执行生成的计划事件时,执行失败并出现错误。
ALTER EVENTDO
SELECT仅返回结果集的或
之类的语句SHOW在事件中使用时无效;这些的输出不会发送到 MySQL Monitor,也不会存储在任何地方。但是,您可以使用诸如
SELECT ...
INTO和
之类的语句INSERT INTO ...
SELECT来存储结果。(有关后者的实例,请参阅本节中的下一个示例。)
事件所属的模式是DO子句中表引用的默认模式。对其他模式中表的任何引用都必须使用正确的模式名称进行限定。
与存储例程一样,您可以通过使用and关键字在DO子句
中使用复合语句语法,如下所示:
BEGINEND
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命令更改语句分隔符。请参阅
第 23.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);如果一个事件的定义者有足够的权限来设置全局系统变量(参见 第 5.1.8.1 节,“系统变量权限”),该事件可以读取和写入全局变量。由于授予此类特权可能会导致滥用,因此在这样做时必须格外小心。
通常,任何在存储例程中有效的语句都可以用于事件执行的动作语句。有关存储例程中允许的语句的更多信息,请参阅第 23.2.1 节,“存储例程语法”。您可以创建一个事件作为存储例程的一部分,但一个事件不能由另一个事件创建。