MySQL 8.0 リファレンスマニュアル


13.1.13 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}

このステートメントは、新しいイベントを作成してスケジュールします。 イベントスケジューラが有効になっていないかぎり、イベントは実行されません。 イベントスケジューラのステータスをチェックし、必要に応じてそれを有効にする方法については、セクション25.4.2「イベントスケジューラの構成」を参照してください。

CREATE EVENT には、イベントが作成されるスキーマに対する EVENT 権限が必要です。 DEFINER 句が存在する場合、セクション25.6「ストアドオブジェクトのアクセス制御」 で説明されているように、必要な権限は user の値によって異なります。

有効な CREATE EVENT ステートメントの最小要件は次のとおりです。

  • キーワード CREATE EVENT に加えて、データベーススキーマ内のイベントを一意に識別するイベント名。

  • イベントが実行される時期と頻度を決定する ON SCHEDULE 句。

  • イベントによって実行される SQL ステートメントを含む DO 句。

最小限の 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 ステートメントを実行することによって (その作成の 1 時間後に) 1 回実行されます。

event_name は、最大長が 64 文字の有効な MySQL 識別子である必要があります。 イベント名では大/小文字が区別されないため、myeventMyEvent という名前のイベントを同じスキーマに含めることはできません。 一般に、イベント名を管理するルールは、ストアドルーチンの名前の場合と同じです。 セクション9.2「スキーマオブジェクト名」を参照してください。

イベントはスキーマに関連付けられています。 event_name の一部としてスキーマが示されていない場合は、デフォルトの (現在の) スキーマと見なされます。 イベントを特定のスキーマ内に作成するには、schema_name.event_name 構文を使用して、そのイベント名をスキーマで修飾します。

DEFINER 句は、イベントの実行時にアクセス権限を確認するときに使用される MySQL アカウントを指定します。 DEFINER 句が存在する場合、user 値は'user_name'@'host_name'CURRENT_USER または CURRENT_USER() として指定された MySQL アカウントである必要があります。 許可される user 値は、セクション25.6「ストアドオブジェクトのアクセス制御」 で説明されているように、保持する権限によって異なります。 イベントセキュリティの詳細は、そのセクションも参照してください。

DEFINER 句を省略すると、デフォルトの定義者は CREATE EVENT ステートメントを実行するユーザーになります。 これは、明示的に DEFINER = CURRENT_USER を指定するのと同じです。

イベント本体内では、CURRENT_USER 関数は、DEFINER ユーザーであるイベント実行時の権限のチェックに使用されるアカウントを返します。 イベント内のユーザー監査については、セクション6.2.22「SQL ベースのアカウントアクティビティ監査」を参照してください。

CREATE EVENT での IF NOT EXISTS には、CREATE TABLE での場合と同じ意味があります。event_name という名前のイベントが同じスキーマ内にすでに存在する場合、アクションは実行されず、エラーも発生しません。 (ただし、このような場合は警告が生成されます。)

ON SCHEDULE 句は、そのイベントに対して定義された event_body を繰り返す時期、頻度、および期間を決定します。 この句は、次の 2 つの形式のいずれかを取ります。

  • 1 回限りのイベントには、AT timestamp が使用されます。 これは、そのイベントが timestamp で指定された日付と時間に 1 回だけ実行されることを指定します。この値は、日付と時間の両方を含んでいるか、または 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.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 を使用できます。 このような場合、イベントは、作成されるとすぐに機能します。

    現在の日付と時間を基準にした将来のある時点 (今から 3 週間後というフレーズで表される時点など) に発生するイベントを作成するには、オプションの句 + INTERVAL interval を使用できます。 interval 部分は数量と時間単位で構成され、時間間隔 で説明されている構文ルールに従いますが、イベントの定義時にマイクロ秒を含む単位キーワードは使用できません。 一部の間隔型では、複合の時間単位を使用できます。 たとえば、2 分と 10 秒は、+ INTERVAL '2:10' MINUTE_SECOND として表すことができます。

    また、間隔を組み合わせることもできます。 たとえば、AT CURRENT_TIMESTAMP + INTERVAL 3 WEEK + INTERVAL 2 DAY は、今から 3 週間と 2 日後と同等です。 このような句の各部分は、+ INTERVAL で始まる必要があります。

  • アクションを定期的に繰り返すには、EVERY 句を使用します。 EVERY キーワードのあとに、前の AT キーワードの説明に示されている interval を指定します。(EVERY では + INTERVAL は使用されません。) たとえば、EVERY 6 WEEK6 週間ごとを示します。

    EVERY 句では + INTERVAL 句は許可されていませんが、+ INTERVAL 内で許可されているのと同じ複合の時間単位を使用できます。

    EVERY 句には、オプションの STARTS 句を含めることができます。 STARTS のあとに、このアクションがいつ繰り返しを開始するかを示す timestamp 値を指定します。また、+ INTERVAL interval を使用して、今からの時間を指定することもできます。 たとえば、EVERY 3 MONTH STARTS CURRENT_TIMESTAMP + INTERVAL 1 WEEK は、今から 1 週間後に開始して 3 か月ごとを示します。 同様に、今から 6 時間と 15 分後から開始して 2 週ごとを、EVERY 2 WEEK STARTS CURRENT_TIMESTAMP + INTERVAL '6:15' HOUR_MINUTE として表すことができます。 STARTS を指定しないことは、STARTS CURRENT_TIMESTAMP を使用することと同じです。つまり、イベントに対して指定されたアクションは、そのイベントが作成されるとただちに繰り返しを開始します。

    EVERY 句には、オプションの ENDS 句を含めることができます。 ENDS キーワードのあとに、このイベントがいつ繰り返しを停止するかを MySQL に指示する timestamp 値を指定します。 また、ENDS とともに + INTERVAL interval を使用することもできます。たとえば、EVERY 12 HOUR STARTS CURRENT_TIMESTAMP + INTERVAL 30 MINUTE ENDS CURRENT_TIMESTAMP + INTERVAL 4 WEEK は、今から 30 分後に開始し、今から 4 週間後に終了するまで 12 時間ごとと同等です。 ENDS を使用しないことは、このイベントがいつまでも実行を続行することを示します。

    ENDS は、複合の時間単位に対して STARTS と同じ構文をサポートします。

    EVERY 句では、STARTS または ENDS、あるいはその両方を使用できます。また、どちらも使用しないことも可能です。

    繰り返しイベントがスケジュール間隔内に終了しない場合は、イベントの複数のインスタンスが同時に実行される可能性があります。 これが好ましくない場合は、同時インスタンスを回避するためのメカニズムを設けてください。 たとえば、GET_LOCK() 関数や、行またはテーブルのロックを使用できます。

ON SCHEDULE 句では、組み込みの MySQL 関数やユーザー変数を含む式を使用して、そこに含まれているすべての timestamp または interval 値を取得できます。 このような式でストアドファンクションやユーザー定義関数を使用したり、テーブル参照を使用したりすることはできません。ただし、SELECT FROM DUAL は使用できます。 これは、CREATE EVENT ステートメントと ALTER EVENT ステートメントの両方に当てはまります。 このような場合のストアドファンクション、ユーザー定義関数、およびテーブルへの参照は明確に禁止されており、エラーで失敗します (Bug #22830 を参照してください)。

ON SCHEDULE 句の時間は、現在のセッションの time_zone 値を使用して解釈されます。 これがイベントのタイムゾーン、つまり、イベントのスケジューリングに使用され、イベントが実行されるとそのイベント内で有効になるタイムゾーンになります。 これらの時間は UTC に変換され、イベントタイムゾーンとともに内部的に格納されます。 これにより、サーバータイムゾーンまたはサマータイムの影響に対し生じた変更とは無関係に、定義されたとおりにイベントの実行を処理できます。 イベントの時間の表現の詳細は、セクション25.4.4「イベントメタデータ」を参照してください。 セクション13.7.7.18「SHOW EVENTS ステートメント」およびセクション26.14「INFORMATION_SCHEMA EVENTS テーブル」も参照してください。

通常は、イベントの期限が切れると、そのイベントはただちに削除されます。 この動作は、ON COMPLETION PRESERVE を指定することによってオーバーライドできます。 ON COMPLETION NOT PRESERVE を使用すると、単にデフォルトの非持続性の動作が明示的になるだけです。

DISABLE キーワードを使用すると、イベントは作成するが、それがアクティブにならないようにすることができます。 あるいは、ENABLE を使用して、デフォルトステータス (アクティブ) を明示的にすることもできます。 これは、ALTER EVENT と組み合わせるともっとも有効です (セクション13.1.3「ALTER EVENT ステートメント」を参照してください)。

3 番目の値は、ENABLE または DISABLE のかわりに表示されることもあります。DISABLE ON SLAVE は、イベントがレプリケーションソースサーバー上で作成され、レプリカにレプリケートされたが、レプリカ上では実行されなかったことを示すために、レプリカ上のイベントのステータスに設定されます。 セクション17.5.1.16「呼び出される機能のレプリケーション」を参照してください。

COMMENT 句を使用して、イベントに対するコメントを指定できます。comment には、イベントの説明に使用する、最大 64 文字の任意の文字列を指定できます。 コメントテキストは文字列リテラルであるため、引用符で囲む必要があります。

DO 句は、イベントによって実行されるアクションを指定するものであり、SQL ステートメントで構成されます。 ストアドルーチンで使用できる有効な MySQL ステートメントのほぼすべてを、スケジュールされたイベントのアクションステートメントとしても使用できます。 (セクション25.8「ストアドプログラムの制約」を参照してください。) たとえば、次のイベント e_hourly は、sessions テーブルのすべての行を 1 時間に 1 回削除します。ここで、このテーブルは 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 ステートメントは成功したように見えます。ただし、結果として得られるスケジュールされたイベントをサーバーが実行しようとすると、その実行はエラーで失敗します。

注記

単に結果セットを返す SELECTSHOW などのステートメントは、イベントで使用されても何の効果もありません。これらのステートメントからの出力は MySQL モニターに送信されず、またどこにも格納されません。 ただし、結果を格納する SELECT ... INTOINSERT INTO ... SELECT などのステートメントは使用できます。 (後者の例については、このセクションにある次の例を参照してください。)

イベントが属するスキーマは、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 コマンドを使用して、ステートメント区切り文字を変更します。 セクション25.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.9.1「システム変数権限」 を参照)、イベントはグローバル変数の読取りおよび書込みを実行できます。 このような権限を付与するには不正利用の可能性があるため、十分に注意する必要があります。

一般に、ストアドルーチンで有効なすべてのステートメントを、イベントによって実行されるアクションステートメントに使用できます。 ストアドルーチン内で許可されるステートメントの詳細は、セクション25.2.1「ストアドルーチンの構文」 を参照してください。 ストアドルーチンの一部としてイベントを作成できますが、イベントを別のイベントで作成することはできません。


関連キーワード:  ステートメント, イベント, CREATE, EVENT, TABLE, 実行, INTERVAL, 参照, DROP, スキーマ