CREATE EVENT语句
CREATE [DEFINER = user]EVENT [IF NOTEXISTS ] event_nameON 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 }
该语句创建并安排一个新事件。除非启用了事件计划程序,否则事件将不会运行。有关检查事件调度程序状态并在必要时启用它的信息,请参见“事件计划程序配置”。
CREATE EVENT
需要EVENT
在其中创建事件的架构的特权。如果DEFINER
存在该子句,则所需的特权取决于该user
值,如“存储的对象访问控制”中所述。
有效CREATE EVENT
声明的最低要求如下:
- 关键字
CREATE EVENT
加上事件名称,可在数据库架构中唯一标识事件。 - 一个
ON SCHEDULE
子句,用于确定事件的执行时间和频率。 - 一个
DO
条款,其中包含SQL语句由事件执行。
这是一个最小CREATE EVENT
声明的示例:
CREATE EVENT myeventON SCHEDULE AT CURRENT_TIMESTAMP +INTERVAL 1HOUR DO UPDATE myschema.mytableSET mycol = mycol + 1;
上一条语句创建一个名为的事件myevent
。通过运行一条将myschema.mytable
表的mycol
列的值增加1的SQL语句,此事件在创建后的一小时内执行一次。
在event_name
必须与64个字符的最大长度一个有效的MySQL标识符。事件名称不区分大小写,因此您不能在同一模式中命名myevent
和的两个事件MyEvent
。通常,管理事件名称的规则与存储例程名称的规则相同。请参见“模式对象名称”。
事件与架构相关联。如果未将模式指示为的一部分event_name
,则采用默认(当前)模式。要在特定架构中创建事件,请使用语法用架构限定事件名称。schema_name.event_name
该DEFINER
子句指定在事件执行时检查访问权限时要使用的MySQL帐户。如果DEFINER
子句,该user
值应被指定为一个MySQL帐户,或。允许的值取决于您拥有的特权,如“存储的对象访问控制”中所述。另请参阅该部分以获取有关事件安全性的其他信息。'user_name'@'host_name'
CURRENT_USER
CURRENT_USER()
user
如果DEFINER
省略该子句,则默认定义器是执行该CREATE EVENT
语句的用户。这与DEFINER = CURRENT_USER
显式指定相同。
在事件主体内,该CURRENT_USER
函数返回DEFINER
用户在事件执行时用于检查特权的帐户。有关事件内用户审核的信息,请参见“基于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.totalsVALUES (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
用来指定当前日期和时间。在这种情况下,事件在创建后立即起作用。为了创建这发生在相对于当前日期和时间,如由短语表示未来在某些点事件“三周,现在”-你可以使用可选的条款。该部分由数量和时间单位两部分组成,并遵循“时间间隔”中描述的语法规则,但在定义事件时不能使用任何涉及微秒的unit关键字。对于某些间隔类型,可以使用复杂的时间单位。例如,“ 2分10秒”可以表示为。
+ 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
。如果重复事件未在其调度间隔内终止,则结果可能是事件的多个实例同时执行。如果这是不希望的,则应建立一种机制来防止同时发生实例。例如,您可以使用
GET_LOCK()
函数,或行或表锁定。
该ON SCHEDULE
子句可以使用涉及内置MySQL函数和用户变量的表达式来获取其包含的timestamp
或interval
值。您不得在此类表达式中使用存储的函数或用户定义的函数,也不得使用任何表引用。但是,您可以使用SELECT FROM DUAL
。对于CREATE EVENT
和ALTER EVENT
语句都是如此。在这种情况下,明确不允许引用存储的函数,用户定义的函数和表,并且它们会因错误而失败(请参见Bug#22830)。
在时代ON SCHEDULE
条款使用当前会话解释time_zone
值。这成为事件时区;也就是说,用于事件调度的时区,在事件执行时有效。这些时间将转换为UTC,并与事件时区一起在内部存储。这使事件执行可以按定义进行,而不管服务器时区的任何后续更改或夏时制如何影响。有关事件时间表示的更多信息,请参见“事件元数据”。另请参见“ SHOW EVENTS语句”和“ INFORMATION_SCHEMA EVENTS表”。
通常,一旦事件过期,它将立即被丢弃。您可以通过指定来覆盖此行为ON COMPLETION PRESERVE
。ON COMPLETION NOT PRESERVE
仅使用可使默认的非持久行为明确。
您可以使用DISABLE
关键字创建事件,但阻止其处于活动状态。或者,您可以使用ENABLE
来使默认状态显式激活。结合使用最有用ALTER EVENT
(请参见“ ALTER EVENT语句”)。
第三个值也可以代替ENABLE
或出现DISABLE
。DISABLE ON SLAVE
在复制从属服务器上为事件的状态设置了,以指示该事件已在主服务器上创建并复制到从属服务器,但未在从属服务器上执行。
您可以使用COMMENT
子句为事件提供注释。comment
可以是您希望用于描述事件的最多64个字符的任何字符串。注释文本是字符串文字,必须用引号引起来。
该DO
子句指定事件所执行的操作,并由一条SQL语句组成。几乎可以在存储例程中使用的任何有效MySQL语句也可以用作计划事件的操作语句。(请参见“对存储程序的限制”。)例如,以下事件每小时一次e_hourly
从sessions
表中删除所有行,而该表是site_activity
模式的一部分:
CREATE EVENT e_hourlyON SCHEDULE EVERY 1HOUR COMMENT 'Clears out sessions table each hour.'DO DELETE FROM site_activity.sessions;
sql_mode
当事件被创建或更改时, MySQL将存储有效的系统变量设置,并且始终在该设置生效的情况下执行事件,而不管事件开始执行时当前的服务器SQL模式如何。
一个CREATE EVENT
包含一个声明ALTER EVENT
它在声明中DO
条款似乎是成功的;但是,当服务器尝试执行生成的计划事件时,执行失败并显示错误。
注意诸如
SELECT
或SHOW
仅返回结果集的语句在事件中使用时无效。它们的输出不会发送到MySQL Monitor,也不会存储在任何地方。但是,您可以使用诸如SELECT ... INTO
和INSERT INTO ... SELECT
存储结果的语句。(有关后者的实例,请参阅本节中的下一个示例。)
事件所属的模式是该DO
子句中表引用的默认模式。对其他模式中的表的任何引用都必须使用正确的模式名称进行限定。
与存储例程一样,可以DO
通过使用BEGIN
and END
关键字在子句中使用复合语句语法,如下所示:
delimiter |CREATE EVENT e_dailyON SCHEDULE EVERY 1 DAYCOMMENT '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
命令更改语句定界符。请参见“定义存储程序”。
事件中可能会出现更复杂的复合语句,例如在存储例程中使用的复合语句。此示例使用局部变量,错误处理程序和流控制构造:
delimiter |CREATE EVENT eON SCHEDULE EVERY 5SECOND DO BEGIN DECLARE v INTEGER;DECLARE CONTINUE HANDLER FOR SQLEXCEPTION BEGIN END ;SET v = 0;WHILE v < 5DO INSERT INTO t1VALUES (0);UPDATE t2SET s1 = s1 + 1;SET v = v + 1;END WHILE ;END |delimiter ;
无法将参数直接传递给事件或从事件传递参数。但是,可以在事件中使用参数调用存储的例程:
CREATE EVENT e_call_myprocON SCHEDULE AT CURRENT_TIMESTAMP +INTERVAL 1 DAYDO CALL myproc(5, 27);
如果事件的定义者具有足以设置全局系统变量的特权(请参见“系统变量特权”),则事件可以读取和写入全局变量。由于授予此类特权会带来滥用的可能性,因此必须格外小心。
通常,在存储例程中有效的任何语句都可以用于事件执行的动作语句。有关存储例程中允许的语句的更多信息,请参见“存储例程语法”。您可以将事件创建为存储例程的一部分,但是另一个事件不能创建一个事件。