1. 程式人生 > >Mysql-13章-SQL語句的語法 (翻譯+理解)

Mysql-13章-SQL語句的語法 (翻譯+理解)

13.1 資料定義語句

13.1.12 建立Event語法

原文 P1894 CREATE [DEFINER = { user | CURRENT_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}

  使用此語句將建立並排程一個新的事件,如果你的事件排程器(Event Scheduler)沒有設定為ON狀態,這個新的事件不會執行,關於事件排程器請見章節 23.4.2

CREATE EVENT 需要EVENT許可權,如果DEFINER定義了一個高許可權的的使用者,你的許可權也要很高,否則你建立不了。

1.主要構成 建立一個新事件的語法最少需要三個部分: 第一部分CREATE EVENT 限定了新事件的名字(需要唯一,不超過64個字元,大小寫不敏感) 第二部分ON SCHEDULE決定了事件執行的時間間隔 第三部分DO決定了事件要執行的SQL語句

這裡有個例子, 定義了一個名為myevent的事件,一小時之後把mytable表中的所有mycol值都+1: CREATE

EVENT myevent ON SCHEDULE AT CURRENT_TIMESTAMP + INTERVAL 1 HOUR DO UPDATE myschema.mytable SET mycol = mycol + 1;

DEFINER部分指定了事件執行時候檢查其執行許可權的使用者是誰,預設是當前執行建立事件的使用者,如果你指定了值,此值必須是msyql使用者之一,其形式可以是'user_name'@'host_name', CURRENT_USER, CURRENT_USER()這三種之一,更多事件安全的問題請見 章節23.6

  IF NOT EXISTS和你建立表時候的意思一樣,如果當前事件已經存在,則不會建立新的事件,只是會有個警告資訊而已。

ON SCHEDULE有兩種形式,你可以任選其一:

  1. AT timestamp表明是一次性事件,timestamp必須是一個日期時間值,不能只有日期而沒有時間,你可以指定其為 DATETIME型別或者TIMESTAMP型別。如果你指定的日期時間是過去的,會生成一條警告資訊,例如: 在這裡插入圖片描述 + INTERVAL interval部分用來指定時間間隔,interval包含兩個部分,一個整數和一個時間單位,聯合的時間表達式也可以,比如2分10秒可以寫成+ INTERVAL '2:10' MINUTE_SECOND(等價於+ INTERVAL 2 MINUTE + INTERVAL 10 SECOND)更多聯合時間請見定義部分

  2. Every表明是重複性事件,可以使用interval部分,不能用 + INTERVALEVERY '2:10' MINUTE_SECOND 表明每2分10秒執行一次該事件。   Every選項還有兩個附加引數 STARTSENDS 其意思很明確,指定事件開始和結束的時間,如果不指定STARTS引數,它等價於取事件建立完畢的時間。一個使用例子: EVERY 12 HOUR STARTS CURRENT_TIMESTAMP INTERVAL 30 MINUTE ENDS CURRENT_TIMESTAMP + INTERVAL 4 WEEK 它表明從30分鐘以後開始到4周以後結束,期間每12小時執行一次事件。   如果一個重複性事件沒有在其週期內完成,可能會導致同一時間內有多個事件例項程序在執行,如果你想避免這種行為可以使用保護機制,例如GET_LOCK()方法或者 給行、表上鎖

ON SCHEDULE 裡面還可以用mysql函式或使用者變數來儲存時間間隔(下圖所示),但是不能用儲存函式或使用者自定義的函式來存時間間隔,table references也不行. 在這裡插入圖片描述 還有一種情況也不允許儲存時間間隔,我不知道怎麼用,把原文貼上來 在這裡插入圖片描述ON SCHEDULE部分的時間表現值由會話中的變數time_zone來決定,預設使用UTC。

2.其他可用部分 (1)如果你想在事件結束後保留這個例項,可以增加ON COMPLETION PRESERVE欄位 (2)事件建立完畢是否馬上啟用取決於ENABLEDISABLE選項,這在你修改事件語句的時候很有用。第三個引數DISABLE ON SLAVE不太明白(原文:is set for the status of an event on a replication slave to indicate that the event was created on the master and replicated to the slave, but is not executed on the slave) (3)使用COMMENT 'string',你還可以為事件提供一個註釋說明,長度在64位以內

3.注意事項 (1)mysql的 sql_mode變數會影響事件的建立、修改和執行 (2)建立事件中的SQL語句可以是修改事件的語句,但是事件執行的時候會失敗。 (3)建立事件中的SQL語句可以是select或show語句,但是其查詢結果不會顯示,你可以用select ... into等儲存結果的語句來看查詢結果。 (4)建立事件中的SQL語句如果很長,你可以用BEGIN ...END來包裹。例子如下(使用了delimiter來重新定義結束符): 在這裡插入圖片描述 (5)無法給事件傳遞引數或者從事件傳遞引數,但是可以在事件中呼叫帶引數的儲存過程。 (6)如果事件的定義者(difiner)有足夠的許可權來設定全域性系統變數,他定義的事件就可以濫用或設定全域性變數,請小心使用。

5.自定義例子 事件:

CREATE DEFINER='bbs'@'localhost' EVENT bbs_blog.addopt on SCHEDULE  EVERY 10 SECOND STARTS CURRENT_TIMESTAMP + INTERVAL '1:10' MINUTE_SECOND ENDS CURRENT_TIMESTAMP + INTERVAL 2 MINUTE + INTERVAL 10 SECOND on COMPLETION PRESERVE COMMENT 'testevent' DO UPDATE bbs_blog.test set sid=sid+1 WHERE id=2;

  這裡定義了一個事件 bbs_blog.addopt其作用是在1分10秒後到2分10 之間每10秒將bbs_blog資料庫的表test中id為2的記錄sid欄位+1,將此事件儲存在mysql資料庫的event表中並提供了註釋說明。

問題:   1分10秒後sid沒有增加,直到事件區間結束也沒有增加。 解決:   (1)設定事件排程器為開啟狀態   show VARIABLES like '%event_scheduler%'; 結果是OFF   開啟:set global event_scheduler=ON;   (2)在event表中刪除對應的事件,並再次建立事件   DELETE from mysql.event where name='addopt1';