• 首页
  • vue
  • TypeScript
  • JavaScript
  • scss
  • css3
  • html5
  • php
  • MySQL
  • redis
  • jQuery
  • CREATE EVENT语句

    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存在该子句,则所需的特权取决于该user值,如“存储的对象访问控制”中所述。

    有效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必须与64个字符的最大长度一个有效的MySQL标识符。事件名称不区分大小写,因此您不能在同一模式中命名myevent和的两个事件MyEvent。通常,管理事件名称的规则与存储例程名称的规则相同。请参见“模式对象名称”。

    事件与架构相关联。如果未将模式指示为的一部分event_name,则采用默认(当前)模式。要在特定架构中创建事件,请使用语法用架构限定事件名称。schema_name.event_name

    DEFINER子句指定在事件执行时检查访问权限时要使用的MySQL帐户。如果DEFINER子句,该user值应被指定为一个MySQL帐户,或。允许的值取决于您拥有的特权,如“存储的对象访问控制”中所述。另请参阅该部分以获取有关事件安全性的其他信息。'user_name'@'host_name'CURRENT_USERCURRENT_USER()user

    如果DEFINER省略该子句,则默认定义器是执行该CREATE EVENT语句的用户。这与DEFINER = CURRENT_USER显式指定相同。

    在事件主体内,该CURRENT_USER函数返回DEFINER用户在事件执行时用于检查特权的帐户。有关事件内用户审核的信息,请参见“基于SQL的帐户活动审核”。

    IF NOT EXISTS具有相同的含义为CREATE EVENTCREATE TABLE:如果命名的事件event_name已经在相同的模式存在,不采取任何行动,而不会出现错误。(但是,在这种情况下会生成警告。)

    ON SCHEDULE子句确定event_body事件的定义重复的时间,频率和持续时间。此子句采用以下两种形式之一:

    • AT timestamp用于一次性事件。它指定事件仅在由给出的日期和时间执行一次,该时间timestamp必须包括日期和时间,或者必须是可解析为datetime值的表达式。为此,您可以使用DATETIMETIMESTAMP类型的值。如果日期是过去的日期,则会发生警告,如下所示:

      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用来指定当前日期和时间。在这种情况下,事件在创建后立即起作用。

      为了创建这发生在相对于当前日期和时间,如由短语表示未来在某些点事件“三周,现在”-你可以使用可选的条款。该部分由数量和时间单位两部分组成,并遵循“时间间隔”中描述的语法规则,但在定义事件时不能使用任何涉及微秒的unit关键字。对于某些间隔类型,可以使用复杂的时间单位。例如,“ 2分10秒”可以表示为。+ INTERVAL intervalinterval+ 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 intervalEVERY 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时,该事件应停止重复的值。您也可以使用带有; 例如,相当于“每十二小时,从现在开始三十分钟,到现在四周结束”。不使用意味着事件将无限期继续执行。+ INTERVAL intervalENDSEVERY 12 HOUR STARTS CURRENT_TIMESTAMP + INTERVAL 30 MINUTE ENDS CURRENT_TIMESTAMP + INTERVAL 4 WEEKENDS

      ENDS支持复杂时间单位的相同语法STARTS

      您可以在子句中使用STARTS,,ENDS或两者都不使用EVERY

      如果重复事件未在其调度间隔内终止,则结果可能是事件的多个实例同时执行。如果这是不希望的,则应建立一种机制来防止同时发生实例。例如,您可以使用GET_LOCK()函数,或行或表锁定。

    ON SCHEDULE子句可以使用涉及内置MySQL函数和用户变量的表达式来获取其包含的timestampinterval值。您不得在此类表达式中使用存储的函数或用户定义的函数,也不得使用任何表引用。但是,您可以使用SELECT FROM DUAL。对于CREATE EVENTALTER EVENT语句都是如此。在这种情况下,明确不允许引用存储的函数,用户定义的函数和表,并且它们会因错误而失败(请参见Bug#22830)。

    在时代ON SCHEDULE条款使用当前会话解释time_zone值。这成为事件时区;也就是说,用于事件调度的时区,在事件执行时有效。这些时间将转换为UTC,并与事件时区一起在内部存储。这使事件执行可以按定义进行,而不管服务器时区的任何后续更改或夏时制如何影响。有关事件时间表示的更多信息,请参见“事件元数据”。另请参见“ SHOW EVENTS语句”和“ INFORMATION_SCHEMA EVENTS表”。

    通常,一旦事件过期,它将立即被丢弃。您可以通过指定来覆盖此行为ON COMPLETION PRESERVEON COMPLETION NOT PRESERVE仅使用可使默认的非持久行为明确。

    您可以使用DISABLE关键字创建事件,但阻止其处于活动状态。或者,您可以使用ENABLE来使默认状态显式激活。结合使用最有用ALTER EVENT(请参见“ ALTER EVENT语句”)。

    第三个值也可以代替ENABLE或出现DISABLEDISABLE ON SLAVE在复制从属服务器上为事件的状态设置了,以指示该事件已在主服务器上创建并复制到从属服务器,但未在从属服务器上执行。

    您可以使用COMMENT子句为事件提供注释。comment可以是您希望用于描述事件的最多64个字符的任何字符串。注释文本是字符串文字,必须用引号引起来。

    DO子句指定事件所执行的操作,并由一条SQL语句组成。几乎可以在存储例程中使用的任何有效MySQL语句也可以用作计划事件的操作语句。(请参见“对存储程序的限制”。)例如,以下事件每小时一次e_hourlysessions表中删除所有行,而该表是site_activity模式的一部分:

    CREATE EVENT e_hourly
        ON SCHEDULE
          EVERY 1 HOUR
        COMMENT 'Clears out sessions table each hour.'
        DO
          DELETE FROM site_activity.sessions;
    

    sql_mode当事件被创建或更改时, MySQL将存储有效的系统变量设置,并且始终在该设置生效的情况下执行事件,而不管事件开始执行时当前的服务器SQL模式如何

    一个CREATE EVENT包含一个声明ALTER EVENT它在声明中DO条款似乎是成功的;但是,当服务器尝试执行生成的计划事件时,执行失败并显示错误。

    注意

    诸如SELECTSHOW仅返回结果集的语句在事件中使用时无效。它们的输出不会发送到MySQL Monitor,也不会存储在任何地方。但是,您可以使用诸如SELECT ... INTOINSERT INTO ... SELECT存储结果的语句。(有关后者的实例,请参阅本节中的下一个示例。)

    事件所属的模式是该DO子句中表引用的默认模式。对其他模式中的表的任何引用都必须使用正确的模式名称进行限定。

    与存储例程一样,可以DO通过使用BEGINand END关键字在子句中使用复合语句语法,如下所示:

    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);
    

    如果事件的定义者具有足以设置全局系统变量的特权(请参见“系统变量特权”),则事件可以读取和写入全局变量。由于授予此类特权会带来滥用的可能性,因此必须格外小心。

    通常,在存储例程中有效的任何语句都可以用于事件执行的动作语句。有关存储例程中允许的语句的更多信息,请参见“存储例程语法”。您可以将事件创建为存储例程的一部分,但是另一个事件不能创建一个事件。