Documentation Home
MySQL 5.6 リファレンスマニュアル
Download this Manual
EPUB - 7.5Mb
HTML Download (TGZ) - 7.2Mb
HTML Download (Zip) - 7.2Mb


13.1.11 CREATE EVENT 構文

CREATE
    [DEFINER = { user | CURRENT_USER }]
    EVENT
    [IF NOT EXISTS]
    event_name
    ON SCHEDULE schedule
    [ON COMPLETION [NOT] PRESERVE]
    [ENABLE | DISABLE | DISABLE ON SLAVE]
    [COMMENT 'comment']
    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}

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

CREATE EVENT には、イベントが作成されるスキーマに対する EVENT 権限が必要です。このセクションのあとの方で説明されているように、DEFINER 値によっては SUPER 権限も必要になる可能性があります。

有効な 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 という名前の 2 つのイベントを同じスキーマ内に含めることはできません。一般に、イベント名を管理するルールは、ストアドルーチンの名前の場合と同じです。セクション9.2「スキーマオブジェクト名」を参照してください。

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

DEFINER 句は、イベントの実行時にアクセス権限を確認するときに使用される MySQL アカウントを指定します。user 値を指定する場合は、'user_name'@'host_name' (GRANT ステートメントで使用されるのと同じ形式)、CURRENT_USER、または CURRENT_USER() として指定された MySQL アカウントにしてください。DEFINER のデフォルト値は、CREATE EVENT ステートメントを実行するユーザーです。これは、明示的に DEFINER = CURRENT_USER を指定するのと同じです。

DEFINER 句を指定した場合は、次のルールによって有効な DEFINER ユーザーの値が決定されます。

  • SUPER 権限がない場合、許可される唯一の user 値は、リテラルで指定するか、または CURRENT_USER を使用して指定した自分のアカウントです。定義者をほかのアカウントに設定することはできません。

  • SUPER 権限がある場合は、構文として有効な任意のアカウント名を指定できます。そのアカウントが実際に存在しない場合は、警告が生成されます。

  • 存在しない DEFINER アカウントでイベントを作成することはできますが、そのアカウントが存在しない場合は、イベント実行時にエラーが発生します。

イベントのセキュリティーの詳細は、セクション20.6「ストアドプログラムおよびビューのアクセスコントロール」を参照してください。

イベント内では、CURRENT_USER() 関数が、イベント実行時に権限を確認するために使用されるアカウント (DEFINER ユーザー) を返します。イベント内のユーザー監査については、セクション6.3.13「SQL ベースの MySQL アカウントアクティビティーの監査」を参照してください。

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 つの部分で構成され、DATE_ADD() 関数で使用される間隔を管理するのと同じ構文ルールに従います (セクション12.7「日付および時間関数」を参照してください)。また、単位のキーワードも、イベントを定義する場合はマイクロ秒を含む単位を使用できない点を除いて同じです。一部の間隔型では、複合の時間単位を使用できます。たとえば、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 に変換され、イベントのタイムゾーンとともに mysql.event テーブル内に格納されます。これにより、サーバータイムゾーンまたはサマータイムの影響に対し生じた変更とは無関係に、定義されたとおりにイベントの実行を処理できます。イベントの時間の表現の詳細は、セクション20.4.4「イベントメタデータ」を参照してください。セクション13.7.5.19「SHOW EVENTS 構文」およびセクション21.7「INFORMATION_SCHEMA EVENTS テーブル」も参照してください。

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

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

ENABLEDISABLE の代わりに 3 番目の値を使用することもできます。DISABLE ON SLAVE は、イベントがマスター上で作成されてスレーブにレプリケートされたが、まだスレーブ上で実行されていないことを示すために、レプリケーションスレーブ上のイベントのステータスに対して設定されます。セクション17.4.1.11「呼び出される機能のレプリケーション」を参照してください。

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

DO 句は、イベントによって実行されるアクションを指定するものであり、SQL ステートメントで構成されます。ストアドルーチンで使用できる有効な MySQL ステートメントのほぼすべてを、スケジュールされたイベントのアクションステートメントとしても使用できます。(セクションD.1「ストアドプログラムの制約」を参照してください。)たとえば、次のイベント 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 コマンドを使用して、ステートメント区切り文字を変更します。セクション20.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);

イベントの定義者に SUPER 権限がある場合、そのイベントはグローバル変数の読み取りおよび書き込みが可能です。この権限を付与すると悪用される可能性があるため、これを行う場合は十分に注意する必要があります。

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


User Comments
Sign Up Login You must be logged in to post a comment.