赞
踩
CREATE EVENT
语句在 MySQL 中用于创建一个事件调度器(Event Scheduler)的事件。事件调度器允许你安排数据库任务(如查询、数据更新等)在将来的某个时间点自动执行,或者根据特定的时间间隔重复执行。这对于需要定期执行的任务特别有用,比如数据清理、报表生成等。
- 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}
此语句创建并安排新事件。除非启用事件计划程序,否则事件不会运行。
CREATE EVENT需要创建事件的模式的EVENT权限。如果存在DEFINER子句,则所需的权限取决于用户值。
有效CREATE EVENT语句的最低要求如下:
这是一个最小CREATE EVENT语句的示例:
- 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。
event_name必须是有效的MySQL标识符,最大长度为64个字符。事件名称不区分大小写,因此不能在同一架构中有两个名为myevent和myevent的事件。一般来说,管理事件名称的规则与存储例程名称的规则相同。
事件与架构相关联。如果event_name中没有指定任何模式,则假定为默认(当前)模式。要在特定架构中创建事件,请使用schema_name.event_name语法用架构限定事件名称。
DEFINER子句指定在事件执行时检查访问权限时使用的MySQL帐户。如果存在DEFINER子句,则用户值应该是指定为“user_name”@“host_name”、CURRENT_user或CURRENT_user()的MySQL帐户。
如果省略DEFINER子句,则默认定义者是执行CREATE EVENT语句的用户。这与显式指定DEFINER=CURRENT_USER相同。
在事件体中,CURRENT_USER函数返回用于在事件执行时检查权限的帐户,即DEFINER用户。有关事件中用户审核的信息。
IF NOT EXISTS对CREATE EVENT和CREATE TABLE的含义相同:如果名为EVENT_name的事件已存在于同一架构中,则不会采取任何行动,也不会产生错误结果。(但是,在这种情况下会生成警告。)
ON SCHEDULE子句决定了为事件定义的event_body何时、多久重复一次以及重复多长时间。本条款采用以下两种形式之一:
- 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间隔。间隔部分由两部分组成,即数量和时间单位,并遵循时间间隔中描述的语法规则,但在定义事件时不能使用任何涉及微秒的单位关键字。对于某些区间类型,可以使用复杂的时间单位。例如,“2分10秒”可以表示为+INTERVAL'2:10'MINUTE_SECOND。
您还可以组合间隔。例如,在当前时间戳+间隔3周+间隔2天相当于“从现在起三周零两天”。此类条款的每一部分都必须以+INTERVAL开头。
虽然EVERY子句中不允许使用+INTERVAL子句,但您可以使用+INTERVAL中允许的相同复杂时间单位。
EVERY子句可以包含可选的STARTS子句。STARTS后面是一个时间戳值,指示何时应该开始重复操作,也可以使用+INTERVAL间隔来指定“从现在开始”的时间量。例如,每3个月开始当前时间戳+间隔1周意味着“从现在开始每三个月”。同样,您可以表示“从现在起每两周,从六小时十五分钟开始”,因为每两周从当前时间戳+间隔'6:15'小时分开始。不指定STARTS与使用STARTS CURRENT_TIMESTAMP相同——也就是说,为事件指定的操作在事件创建后立即开始重复。
EVERY子句可以包含可选的ENDS子句。ENDS关键字后面跟一个时间戳值,该值告诉MySQL事件何时应该停止重复。您也可以在ENDS中使用+INTERVAL间隔;例如,每12小时开始电流_时间戳+间隔30分钟结束电流_时间戳记+间隔4周相当于“每12小时,从现在开始30分钟,到现在结束四周”。不使用ENDS意味着事件会无限期地继续执行。
ENDS支持与STARTS相同的复杂时间单位语法。
您可以在EVERY子句中使用开始、结束或两者都不使用。
如果重复事件未在其调度间隔内终止,则结果可能是该事件的多个实例同时执行。如果这是不可取的,您应该建立一种机制来防止同时发生实例。例如,您可以使用GET_LOCK()函数,或行或表锁定。
ON SCHEDULE子句可以使用涉及内置MySQL函数和用户变量的表达式来获取它包含的任何时间戳或间隔值。您不得在此类表达式中使用存储函数或可加载函数,也不得使用任何表引用;但是,您可以使用SELECT FROM DUAL。CREATE EVENT和ALTER EVENT语句都是如此。在这种情况下,特别不允许引用存储函数、可加载函数和表,并且会因错误而失败(参见Bug#22830)。
ON SCHEDULE子句中的时间使用当前会话时区值进行解释。这将成为事件时区;即用于事件调度并且在事件执行时在事件内有效的时区。这些时间转换为UTC,并与事件时区一起存储在内部。这使得事件执行能够按照定义进行,而不管服务器时区或夏令时的任何后续更改。
通常,一旦事件过期,它就会立即被删除。您可以通过指定ON COMPLETION PRESERVE来覆盖此行为。使用ON COMPLETION NOT PRESERVE只会使默认的非持久性行为显式化。
您可以创建事件,但可以使用DISABLE关键字阻止其处于活动状态。或者,您可以使用ENABLE来明确默认状态,即活动状态。这与ALTER EVENT结合使用最为有用。
第三个值也可能出现在“启用”或“禁用”的位置;DISABLE ON SLAVE是为副本上的事件状态设置的,表示该事件是在复制源服务器上创建并复制到副本上的,但不会在副本上执行。
您可以使用comment子句为事件提供注释。注释可以是您希望用于描述事件的最多64个字符的任何字符串。注释文本是字符串文字,必须用引号括起来。
DO子句指定事件执行的操作,由SQL语句组成。几乎任何可以在存储例程中使用的有效MySQL语句都可以用作计划事件的操作语句。例如,以下事件e_hourly每小时从会话表中删除一次所有行,其中该表是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语句似乎成功;然而,当服务器尝试执行由此产生的计划事件时,执行失败并出现错误。
注:
SELECT或SHOW等仅返回结果集的语句在事件中使用时无效;这些输出不会发送到MySQL监视器,也不会存储在任何地方。但是,您可以使用SELECT等语句。。。INTO和INSERT INTO。。。选择存储结果的选项。
事件所属的模式是DO子句中表引用的默认模式。对其他模式中表的任何引用都必须使用正确的模式名称进行限定。
与存储例程一样,您可以通过使用BEGIN和END关键字在DO子句中使用复合语句语法,如下所示:
- 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命令更改语句分隔符。
事件中可能存在更复杂的复合语句,例如存储例程中使用的复合语句。此示例使用局部变量、错误处理程序和流控制构造:
- 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);
如果事件的定义者具有足够的权限来设置全局系统变量,则该事件可以读取和写入全局变量。由于授予此类特权可能会被滥用,因此必须格外小心。
通常,在存储例程中有效的任何语句都可以用于由事件执行的动作语句。无法将事件创建为存储例程的一部分,也无法通过另一个事件创建事件。
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。