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 識別子である必要があります。イベント名は大文字と小文字が区別されないため、myevent
と MyEvent
という名前の 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 WEEK
は「6 週間ごと」を示します。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 構文」を参照してください)。
ENABLE
や DISABLE
の代わりに 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
ステートメントは成功したように見えます。ただし、結果として得られるスケジュールされたイベントをサーバーが実行しようとすると、その実行はエラーで失敗します。
単に結果セットを返す SELECT
や SHOW
などのステートメントは、イベントで使用されても何の効果もありません。これらのステートメントからの出力は MySQL モニターに送信されず、またどこにも格納されません。ただし、結果を格納する SELECT ... INTO
や INSERT 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「ストアドルーチンの構文」を参照してください。ストアドルーチンの一部としてイベントを作成できますが、イベントを別のイベントで作成することはできません。