13.1.12 创建事件语法 (CREATE EVENT Syntax)
ALTER
[DEFINER = { user | CURRENT_USER }]
EVENT event_name
[ON SCHEDULE schedule]
[ON COMPLETION [NOT] PRESERVE]
[RENAME TO new_event_name]
[ENABLE | DISABLE | DISABLE ON SLAVE]
[COMMENT 'string']
[DO event_body]
此声明创建并安排新的事件。除非事件计划程序已启用,否则该事件将不会运行。
CREATE EVENT
需要 EVENT
特权才能创建事件的模式。可能还需要 SET_USER_ID
或 SUPER
特权,具体取决于 DEFINER
值
有效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
表格的 mycol
列的值递增 1 的 SQL 语句。event_name
必须是有效的 MySQL 标识符,最大长度为64个字符。myevent
和 MyEvent
的事件。一个事件与一个模式相关联。
如果没有模式被指定为event_name
的一部分,则假定默认(当前)模式。
要在特定模式中创建事件,请使用schema_name.event_name
语法使用模式限定事件名称。
解释:
CREATE
[DEFINER = { user | CURRENT_USER }]
EVENT
DEFINER
子句指定在事件执行时检查访问特权时要使用的MySQL帐户。
如果给出用户值,它应该是指定为'user_name'@'host_name'
,CURRENT_USER
或CURRENT_USER()
的MySQL帐户。
DEFINER
的默认值是执行CREATE EVENT
语句的用户。 这与明确指定DEFINER = CURRENT_USER
相同。
如果指定了DEFINER
子句,则这些规则将确定有效的DEFINER用户值:
如果您没有SET_USER_ID
或SUPER
权限,则唯一允许的用户值是您自己的帐户,可以按字面或使用CURRENT_USER
指定。 您无法将定义者设置为某个其他帐户。
如果您具有SET_USER_ID
或SUPER
权限,则可以指定任何语法上有效的帐户名称。 如果该帐户不存在,则会生成警告。
尽管可以使用不存在的DEFINER
帐户创建事件,但如果该帐户不存在,则会在事件执行时发生错误。
在事件中,CURRENT_USER()
函数返回用于在事件执行时检查权限的帐户,该帐户是DEFINER
用户。
解释:
[IF NOT EXISTS]
event_name
IF NOT EXISTS
对于CREATE EVENT
具有与CREATE TABLE
相同的含义:如果名称为event_name
的事件已存在于同一模式中,则不采取任何操作,并且不会产生错误。 (但是,在这种情况下会产生警告。)
解释:
ON SCHEDULE schedule
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}
ON SCHEDULE
子句确定event_body
为事件定义的 时间, 频率 和 时长 。
本条款采取两种形式之一:
AT timestamp
用于一次性事件。
它指定事件只在指定的日期和时间执行一次 timestamp,其中必须包含日期和时间,或者必须是解析为日期时间值的表达式。
您可以为此使用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
指定当前的日期和时间。
在这种情况下,事件一旦创建就会发挥作用。
要创建相对于当前日期和时间在将来某个时间点发生的事件 - 例如用“ 从现在开始三周 ”表达的事件 - 可以使用可选的子句。
该 部分由数量和时间单位两部分组成,并遵循相同的语法规则来管理函数中使用的时间间隔 。
单位关键字也是 除了在定义一个事件时不能使用任何涉及微秒的单位,对于一些间隔类型,可以使用复杂的时间单位,例如,“2分钟和10秒”可以表示为+ INTERVAL '2:10' MINUTE_SECOND
。
合并间隔。
例如,AT CURRENT_TIMESTAMP + INTERVAL 3 WEEK INTERVAL 2 DAY
相当于“从现在开始的三周和两天”。 这种条款的每一部分必须以+ INTERVAL
开头。
EVERY
子句:定期重复操作。
EVERY
关键字后跟一个interval
,如前面关于AT
关键字的讨论中所述。 (+ INTERVAL
并不适用于每件事。)例如,EVERY 6 WEEK
是指“ 每六周 ”
虽然在EVERY
子句中不允许使用+ INTERVAL
子句,但可以使用+ INTERVAL
中允许的相同复杂时间单位。
EVERY
子句可以包含一个可选的STARTS
子句。
STARTS
后跟一个时间戳值,指示何时应该开始重复动作,还可以使用+ INTERVAL
间隔来指定“从现在开始”的时间量。
例如,EVERY 3 MONTH STARTS CURRENT_TIMESTAMP + INTERVAL 1 WEEK
意味着“每三个月,从现在起一周开始”。
同样,EVERY 2 WEEK STARTS CURRENT_TIMESTAMP + INTERVAL '6:15' HOUR_MINUTE
意味着 “每两周,从现在开始6个小时15分钟”。
不指定STARTS
与使用STARTS CURRENT_TIMESTAMP
相同 - 即为事件指定的操作在创建事件时立即开始重复。
不指定STARTS
与使用STARTS CURRENT_TIMESTAMP
相同 - 即为事件指定的操作在创建事件时立即开始重复。
EVERY
子句可以包含一个可选的ENDS
子句。
ENDS
关键字后跟一个时间戳值,告诉MySQL事件应该何时停止重复。
您也可以在ENDS
中使用+ INTERVAL
间隔;
例如“EVERY 12 HOUR STARTS CURRENT_TIMESTAMP + INTERVAL 30 MINUTE ENDS CURRENT_TIMESTAMP + INTERVAL 4 WEEK
”相当于 “每12小时,从现在开始三十分钟开始,从现在开始四周结束”。
不使用ENDS
意味着事件无限期地继续执行。
ENDS
支持与STARTS
一样的复杂时间单位的语法。
在EVERY
子句中可以使用STARTS
,ENDS
,或者都不使用。
如果重复事件不在其调度间隔内终止,则结果可能是同时执行的事件的多个实例。 如果这是不可取的,你应该建立一个机制来防止同时发生的事件。
例如,您可以使用GET_LOCK()
函数或行或表锁定。
ON SCHEDULE
子句可以使用涉及内置MySQL函数和用户变量的表达式来获取它包含的任何时间戳记或间隔值。
您不得在这些表达式中使用存储的函数或用户定义的函数,也不得使用任何表引用; 但是,您可以使用SELECT FROM DUAL
。 对于CREATE EVENT
和ALTER EVENT
语句都是如此。
在这种情况下,对存储的函数,用户定义的函数和表的引用是不允许的,并且会因错误而失败。
ON SCHEDULE
子句中的时间使用当前会话的time_zone
值进行解释。
这成为事件时区; 即用于事件调度的时区,并在执行时在事件内生效。
这些时间转换为UTC
并与mysql.event
表中的事件时区一起存储。
这可以使事件执行按照定义继续进行,而不管后续对服务器时区或夏令时效果所做的任何更改。
解释
[ON COMPLETION [NOT] PRESERVE]
通常,一旦事件已经过期,它会立即被删除。
您可以通过指定ON COMPLETION PRESERVE
来覆盖此行为。
使用ON COMPLETION NOT PRESERVE
只会使默认的非持久行为显式化。
解释
[ENABLE | DISABLE | DISABLE ON SLAVE]
使用DISABLE
关键字阻止事件为活动状态。
使用ENABLE
关键字开启事件为活动状态。
DISABLE ON SLAVE
被设置为复制从站上事件的状态,以指示事件在主站上创建并复制到从站,但不在从站上执行。
解释
[COMMENT 'string']
使用COMMENT
子句为事件提供注释。
注释最多为64个字符。 注释文本是一个字符串文字,必须用引号括起来。
解释
DO event_body;
DO
子句指定事件执行的动作,并由SQL语句组成。
几乎任何可以在存储例程中使用的有效MySQL语句也可以用作预定事件的操作语句。
例如,以下事件每小时从会话表中删除所有行,其中此表是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模式如何。
在其DO
子句中包含ALTER EVENT
语句的CREATE EVENT
语句似乎成功;
但是,当服务器尝试执行结果的预定事件时,执行失败并出现错误。