任務(wù)需求:定時(shí)執(zhí)行的任務(wù),調(diào)用存儲(chǔ)過(guò)程,進(jìn)行數(shù)據(jù)遷移。
存儲(chǔ)過(guò)程相關(guān)總結(jié):(存儲(chǔ)過(guò)程的創(chuàng)建 ?不能伴隨有if exists ?需要提前判斷刪除同名的存儲(chǔ)過(guò)程)
存儲(chǔ)過(guò)程的查看:
select name from mysql.proc where db = your_db_name and type = PROCEDURE
show procedure status;
查看存儲(chǔ)過(guò)程或函數(shù)的創(chuàng)建代碼
show create procedure proc_name;
存儲(chǔ)過(guò)程的創(chuàng)建 語(yǔ)法以及遇到的問(wèn)題
MySQL中,創(chuàng)建存儲(chǔ)過(guò)程的基本形式如下:
CREATE PROCEDURE sp_name ([proc_parameter[,...]])
[characteristic ...] routine_body
其中,sp_name參數(shù)是存儲(chǔ)過(guò)程的名稱(chēng);proc_parameter表示存儲(chǔ)過(guò)程的參數(shù)列表; characteristic參數(shù)指定存儲(chǔ)過(guò)程的特性;routine_body參數(shù)是SQL代碼的內(nèi)容,可以用BEGIN…END來(lái)標(biāo)志SQL代碼的開(kāi)始和結(jié)束。
proc_parameter中的每個(gè)參數(shù)由3部分組成。這3部分分別是輸入輸出類(lèi)型、參數(shù)名稱(chēng)和參數(shù)類(lèi)型。其形式如下:
[ IN | OUT | INOUT ] param_name type
其中,IN表示輸入?yún)?shù);OUT表示輸出參數(shù); INOUT表示既可以是輸入,也可以是輸出; param_name參數(shù)是存儲(chǔ)過(guò)程的參數(shù)名稱(chēng);type參數(shù)指定存儲(chǔ)過(guò)程的參數(shù)類(lèi)型,該類(lèi)型可以是MySQL數(shù)據(jù)庫(kù)的任意數(shù)據(jù)類(lèi)型。
characteristic參數(shù)有多個(gè)取值。其取值說(shuō)明如下:
LANGUAGE SQL:說(shuō)明routine_body部分是由SQL語(yǔ)言的語(yǔ)句組成,這也是數(shù)據(jù)庫(kù)系統(tǒng)默認(rèn)的語(yǔ)言。
[NOT] DETERMINISTIC:指明存儲(chǔ)過(guò)程的執(zhí)行結(jié)果是否是確定的。DETERMINISTIC表示結(jié)果是確定的。每次執(zhí)行存儲(chǔ)過(guò)程時(shí),相同的輸入會(huì)得到相同的輸出。NOT DETERMINISTIC表示結(jié)果是非確定的,相同的輸入可能得到不同的輸出。默認(rèn)情況下,結(jié)果是非確定的。
{ CONTAINS SQL | NO SQL | READS SQL DATA | MODIFIES SQL DATA }:指明子程序使用SQL語(yǔ)句的限制。CONTAINS SQL表示子程序包含SQL語(yǔ)句,但不包含讀或?qū)憯?shù)據(jù)的語(yǔ)句;NO SQL表示子程序中不包含SQL語(yǔ)句;READS SQL DATA表示子程序中包含讀數(shù)據(jù)的語(yǔ)句;MODIFIES SQL DATA表示子程序中包含寫(xiě)數(shù)據(jù)的語(yǔ)句。默認(rèn)情況下,系統(tǒng)會(huì)指定為CONTAINS SQL。
SQL SECURITY { DEFINER | INVOKER }:指明誰(shuí)有權(quán)限來(lái)執(zhí)行。DEFINER表示只有定義者自己才能夠執(zhí)行;INVOKER表示調(diào)用者可以執(zhí)行。默認(rèn)情況下,系統(tǒng)指定的權(quán)限是DEFINER。
COMMENT 'string':注釋信息。
技巧:創(chuàng)建存儲(chǔ)過(guò)程時(shí),系統(tǒng)默認(rèn)指定CONTAINS SQL,表示存儲(chǔ)過(guò)程中使用了SQL語(yǔ)句。但是,如果存儲(chǔ)過(guò)程中沒(méi)有使用SQL語(yǔ)句,最好設(shè)置為NO SQL。而且,存儲(chǔ)過(guò)程中最好在COMMENT部分對(duì)存儲(chǔ)過(guò)程進(jìn)行簡(jiǎn)單的注釋?zhuān)员阋院笤陂喿x存儲(chǔ)過(guò)程的代碼時(shí)更加方便。
創(chuàng)建一個(gè)名為num_from_employee的存儲(chǔ)過(guò)程。代碼如下:
CREATE? PROCEDURE? num_from_employee (IN emp_id INT, OUT count_num INT )
READS SQL DATA
BEGIN
SELECT? COUNT(*)? INTO? count_num
FROM? employee
WHERE? d_id=emp_id ;
END
上述代碼中,存儲(chǔ)過(guò)程名稱(chēng)為num_from_employee;輸入變量為emp_id;輸出變量為count_num。SELECT語(yǔ)句從employee表查詢(xún)d_id值等于emp_id的記錄,并用COUNT(*)計(jì)算d_id值相同的記錄的條數(shù),最后將計(jì)算結(jié)果存入count_num中。代碼的執(zhí)行結(jié)果如下:
mysql> DELIMITER &&
mysql> CREATE? PROCEDURE? num_from_employee
(IN emp_id INT, OUT count_num INT )
-> READS SQL DATA
-> BEGIN
-> SELECT? COUNT(*)? INTO? count_num
-> FROM? employee
-> WHERE? d_id=emp_id ;
-> END &&
Query OK, 0 rows affected (0.09 sec)
mysql> DELIMITER ;
代碼執(zhí)行完畢后,沒(méi)有報(bào)出任何出錯(cuò)信息就表示存儲(chǔ)函數(shù)已經(jīng)創(chuàng)建成功。以后就可以調(diào)用這個(gè)存儲(chǔ)過(guò)程,數(shù)據(jù)庫(kù)中會(huì)執(zhí)行存儲(chǔ)過(guò)程中的SQL語(yǔ)句。
說(shuō)明:MySQL中默認(rèn)的語(yǔ)句結(jié)束符為分號(hào)(;)。存儲(chǔ)過(guò)程中的SQL語(yǔ)句需要分號(hào)來(lái)? ? 結(jié)束。為了避免沖突,首先用"DELIMITER &&"將MySQL的結(jié)束符設(shè)置為&&。最后再用"DELIMITER ;"來(lái)將結(jié)束符恢復(fù)成分號(hào)。這與創(chuàng)建觸發(fā)器時(shí)是一樣的。
一、MySQL 創(chuàng)建存儲(chǔ)過(guò)程
“pr_add” 是個(gè)簡(jiǎn)單的 MySQL 存儲(chǔ)過(guò)程,這個(gè)存儲(chǔ)過(guò)程有兩個(gè) int 類(lèi)型的輸入?yún)?shù) “a”、“b”,返回這兩個(gè)參數(shù)的和。
drop procedure if exists pr_add;
-- 計(jì)算兩個(gè)數(shù)之和
create procedure pr_add
(
a int,
b int
)
begin
declare c int;
if a is null then
set a = 0;
end if;
if b is null then
set b = 0;
end if;
set c = a + b;
select c as sum;
/*
return c;- 不能在 MySQL 存儲(chǔ)過(guò)程中使用。return 只能出現(xiàn)在函數(shù)中。
/
end;
二、調(diào)用Mysql存儲(chǔ)過(guò)程
eg: call pr_add(10,20);
執(zhí)行 MySQL 存儲(chǔ)過(guò)程,存儲(chǔ)過(guò)程參數(shù)為 MySQL 用戶(hù)變量。
set @a = 10;
set @b = 20;
call pr_add(@a, @b);
假定存儲(chǔ)過(guò)程如下:create procedure pr_return2Pr(a int,out b int,inout c int) begin set b =a; set c = a+ c; end
set @cc = 3;call pr_return2Pr(1,@bb,@cc);select @bb,@cc; 返回1,4
如果存儲(chǔ)過(guò)程中變量定義為out,可以不進(jìn)行變量值定義,直接聲明即可。inout? 則需要提前set 變量,然后調(diào)用。
IN為默認(rèn)類(lèi)型,值必須在調(diào)用時(shí)指定,值不能返回(值傳遞)
OUT值可以返回(指針傳遞)
INOUT值必須在調(diào)用時(shí)指定,值可以返回
使用DECLARE來(lái)聲明,DEFAULT賦默認(rèn)值,SET賦值
DECLARE counter INT DEFAULT 0;? - 默認(rèn)為0
SET counter = counter+1;? ? ? ? ? ? ? - 自增+1
三、MySQL 存儲(chǔ)過(guò)程特點(diǎn)
創(chuàng)建 MySQL 存儲(chǔ)過(guò)程的簡(jiǎn)單語(yǔ)法為:
create procedure 存儲(chǔ)過(guò)程名字()
(
[in|out|inout] 參數(shù) datatype
)
begin
MySQL 語(yǔ)句;
end;
MySQL 存儲(chǔ)過(guò)程參數(shù)如果不顯式指定“in”、“out”、“inout”,則默認(rèn)為“in”。習(xí)慣上,對(duì)于是“in” 的參數(shù),我們都不會(huì)顯式指定。
如下,給出解釋
1. MySQL 存儲(chǔ)過(guò)程名字后面的“()”是必須的,即使沒(méi)有一個(gè)參數(shù),也需要“()”
2. MySQL 存儲(chǔ)過(guò)程參數(shù),不能在參數(shù)名稱(chēng)前加“@”,如:“@a int”。下面的創(chuàng)建存儲(chǔ)過(guò)程語(yǔ)法在 MySQL 中是錯(cuò)誤的(在 SQL Server 中是正確的)。 MySQL 存儲(chǔ)過(guò)程中的變量,不需要在變量名字前加“@”,雖然 MySQL 客戶(hù)端用戶(hù)變量要加個(gè)“@”。
create procedure pr_add
(
@a int,- 錯(cuò)誤
b int? - 正確
)
3. MySQL 存儲(chǔ)過(guò)程的參數(shù)不能指定默認(rèn)值。
4. MySQL 存儲(chǔ)過(guò)程不需要在 procedure body 前面加 “as”。而 SQL Server 存儲(chǔ)過(guò)程必須加 “as” 關(guān)鍵字。
create procedure pr_add
(
a int,
b int
)
as? ? ? ? ? ? - 錯(cuò)誤,MySQL 不需要 “as”
begin
mysql statement ...;
end;
5. 如果 MySQL 存儲(chǔ)過(guò)程中包含單條或者多條 MySQL 語(yǔ)句,都需要 begin end 關(guān)鍵字。
create procedure pr_add
(
a int,
b int
)
begin
mysql statement 1 ...;
mysql statement 2 ...;
end;
6.MySQL 存儲(chǔ)過(guò)程中的每條語(yǔ)句的末尾,都要加上分號(hào) “;”
...
declare c int;
if a is null then
set a = 0;
end if;
...
7. MySQL 存儲(chǔ)過(guò)程中的注釋。
/*
這是個(gè)
多行 MySQL 注釋。
/
declare c int;? ? - 這是單行 MySQL 注釋 (注意- 后至少要有一個(gè)空格)
if a is null then 這也是個(gè)單行 MySQL 注釋
set a = 0;
end if;
...
end;
8. 不能在 MySQL 存儲(chǔ)過(guò)程中使用 “return” 關(guān)鍵字。
set c = a + b;
select c as sum;
/*
return c;- 不能在 MySQL 存儲(chǔ)過(guò)程中使用。return 只能出現(xiàn)在函數(shù)中。
/
end;
9. 調(diào)用 MySQL 存儲(chǔ)過(guò)程時(shí)候,需要在過(guò)程名字后面加“()”,即使沒(méi)有一個(gè)參數(shù),也需要“()”
call pr_no_param();
10. 因?yàn)?MySQL 存儲(chǔ)過(guò)程參數(shù)沒(méi)有默認(rèn)值,所以在調(diào)用 MySQL 存儲(chǔ)過(guò)程時(shí)候,不能省略參數(shù)。可以用 null 來(lái)替代。
call pr_add(10, null);
mysql寫(xiě)條件判斷時(shí),注意時(shí)if? elseif? else? 其中elseif之間是不能夠有空格的。
命令行編寫(xiě)存儲(chǔ)過(guò)程命令是一定注意提前delimiter。說(shuō)明:MySQL中默認(rèn)的語(yǔ)句結(jié)束符為分號(hào)(;)。存儲(chǔ)過(guò)程中的SQL語(yǔ)句需要分號(hào)來(lái)? ? 結(jié)束。為了避免沖突,首先用"DELIMITER &&"將MySQL的結(jié)束符設(shè)置為&&。最后再用"DELIMITER ;"來(lái)將結(jié)束符恢復(fù)成分號(hào)。這與創(chuàng)建觸發(fā)器時(shí)是一樣的。但是mysql 窗口就沒(méi)問(wèn)題了。
存儲(chǔ)過(guò)程的刪除: 不能在一個(gè)存儲(chǔ)過(guò)程中刪除另一個(gè)存儲(chǔ)過(guò)程,只能調(diào)用另一個(gè)存儲(chǔ)過(guò)程
drop procedure if exists prName
11,存儲(chǔ)方法
存儲(chǔ)方法與存儲(chǔ)過(guò)程的區(qū)別
1,存儲(chǔ)方法的參數(shù)列表只允許IN類(lèi)型的參數(shù),而且沒(méi)必要也不允許指定IN關(guān)鍵字
2,存儲(chǔ)方法返回一個(gè)單一的值,值的類(lèi)型在存儲(chǔ)方法的頭部定義
3,存儲(chǔ)方法可以在SQL語(yǔ)句內(nèi)部調(diào)用
4,存儲(chǔ)方法不能返回結(jié)果集
mysql事件:創(chuàng)建存儲(chǔ)過(guò)程的時(shí)候,如果采用命令行的方式,需要先修改命令結(jié)束符,將分號(hào)改成其他的符號(hào),注意delimiter時(shí) 不能在$$后添加;? 否則就以$$;? 作為結(jié)束標(biāo)記了。
-- 設(shè)置分隔符為 '$$' ,mysql默認(rèn)的語(yǔ)句分隔符為 ';' ,這樣在后續(xù)的 create 到 end 這段代碼都會(huì)看成是一條語(yǔ)句來(lái)執(zhí)行
DELIMITER $$
//創(chuàng)建存儲(chǔ)過(guò)程或者事件語(yǔ)句
//結(jié)束
$$
- 將語(yǔ)句分割符設(shè)置回 ';'
DELIMITER ;
事件簡(jiǎn)介
事件(event)是MySQL在相應(yīng)的時(shí)刻調(diào)用的過(guò)程式數(shù)據(jù)庫(kù)對(duì)象。一個(gè)事件可調(diào)用一次,也可周期性的啟動(dòng),它由一個(gè)特定的線(xiàn)程來(lái)管理的,也就是所謂的“事件調(diào)度器”。
事件和觸發(fā)器類(lèi)似,都是在某些事情發(fā)生的時(shí)候啟動(dòng)。當(dāng)數(shù)據(jù)庫(kù)上啟動(dòng)一條語(yǔ)句的時(shí)候,觸發(fā)器就啟動(dòng)了,而事件是根據(jù)調(diào)度事件來(lái)啟動(dòng)的。由于他們彼此相似,所以事件也稱(chēng)為臨時(shí)性觸發(fā)器。
事件取代了原先只能由操作系統(tǒng)的計(jì)劃任務(wù)來(lái)執(zhí)行的工作,而且MySQL的事件調(diào)度器可以精確到每秒鐘執(zhí)行一個(gè)任務(wù),而操作系統(tǒng)的計(jì)劃任務(wù)(如:Linux下的CRON或Windows下的任務(wù)計(jì)劃)只能精確到每分鐘執(zhí)行一次。
2 事件的優(yōu)缺點(diǎn)
2.1 優(yōu)點(diǎn)
一些對(duì)數(shù)據(jù)定時(shí)性操作不再依賴(lài)外部程序,而直接使用數(shù)據(jù)庫(kù)本身提供的功能。
可以實(shí)現(xiàn)每秒鐘執(zhí)行一個(gè)任務(wù),這在一些對(duì)實(shí)時(shí)性要求較高的環(huán)境下就非常實(shí)用了。
2.2 缺點(diǎn)
定時(shí)觸發(fā),不可以調(diào)用。
3 創(chuàng)建事件
一條create event語(yǔ)句創(chuàng)建一個(gè)事件。每個(gè)事件由兩個(gè)主要部分組成,第一部分是事件調(diào)度(event schedule),表示事件何時(shí)啟動(dòng)以及按什么頻率啟動(dòng),第二部分是事件動(dòng)作(event action ),這是事件啟動(dòng)時(shí)執(zhí)行的代碼,事件的動(dòng)作包含一條SQL語(yǔ)句,它可能是一個(gè)簡(jiǎn)單地insert或者update語(yǔ)句,也可以使一個(gè)存儲(chǔ)過(guò)程或者benin...end語(yǔ)句塊,這兩種情況允許我們執(zhí)行多條SQL。
一個(gè)事件可以是活動(dòng)(打開(kāi))的或停止(關(guān)閉)的,活動(dòng)意味著事件調(diào)度器檢查事件動(dòng)作是否必須調(diào)用,停止意味著事件的聲明存儲(chǔ)在目錄中,但調(diào)度器不會(huì)檢查它是否應(yīng)該調(diào)用。在一個(gè)事件創(chuàng)建之后,它立即變?yōu)榛顒?dòng)的,一個(gè)活動(dòng)的事件可以執(zhí)行一次或者多次。
3.1 創(chuàng)建語(yǔ)法如下
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}
名詞解釋?zhuān)?/p>
event_name :創(chuàng)建的event名字(唯一確定的)。
ON SCHEDULE:計(jì)劃任務(wù)。
schedule: 決定event的執(zhí)行時(shí)間和頻率(注意時(shí)間一定要是將來(lái)的時(shí)間,過(guò)去的時(shí)間會(huì)出錯(cuò)),有兩種形式 AT和EVERY。
[ON COMPLETION [NOT] PRESERVE]: 可選項(xiàng),默認(rèn)是ON COMPLETION NOT PRESERVE 即計(jì)劃任務(wù)執(zhí)行完畢后自動(dòng)drop該事件;ON COMPLETION? PRESERVE則不會(huì)drop掉。
[COMMENT 'comment'] :可選項(xiàng),comment 用來(lái)描述event;相當(dāng)注釋?zhuān)畲箝L(zhǎng)度64個(gè)字節(jié)。
[ENABLE | DISABLE] :設(shè)定event的狀態(tài),默認(rèn)ENABLE:表示系統(tǒng)嘗試執(zhí)行這個(gè)事件, DISABLE:關(guān)閉該事情,可以用alter修改
DO event_body: 需要執(zhí)行的sql語(yǔ)句(可以是復(fù)合語(yǔ)句)。CREATE EVENT在存儲(chǔ)過(guò)程中使用時(shí)合法的。
定時(shí)器 -- 創(chuàng)建定時(shí)器后會(huì)在mysql 中創(chuàng)建一個(gè)線(xiàn)程用以執(zhí)行該事件。 user就是event_scheduler command-daemon state-waiting for next activation
1.查看定時(shí)器-事件調(diào)度器 MySQL事件調(diào)度器event_scheduler負(fù)責(zé)調(diào)用事件,它默認(rèn)是關(guān)閉的。這個(gè)調(diào)度器不斷地監(jiān)視一個(gè)事件是否要調(diào)用, 要?jiǎng)?chuàng)建事件,必須打開(kāi)調(diào)度器。
show variables like '%event_scheduler%';
2.開(kāi)啟時(shí)間調(diào)度器
命令行:
SET GLOBAL event_scheduler = ON;
SET @@global.event_scheduler = ON;
SET GLOBAL event_scheduler = 1;
SET @@global.event_scheduler = 1;
配置文件:event_scheduler = 1 #或者ON
查看調(diào)度器線(xiàn)程
mysql> show processlist;
+----+-----------------+-----------+------+---------+------+------------------------+------------------+
| Id | User? ? ? ? ? ? | Host? ? ? | db? | Command | Time | State? ? ? ? ? ? ? ? ? | Info? ? ? ? ? ? |
+----+-----------------+-----------+------+---------+------+------------------------+------------------+
|? 2 | root? ? ? ? ? ? | localhost | NULL | Query? |? ? 0 | NULL? ? ? ? ? ? ? ? ? | show processlist |
|? 3 | event_scheduler | localhost | NULL | Daemon? |? ? 6 | Waiting on empty queue | NULL? ? ? ? ? ? |
+----+-----------------+-----------+------+---------+------+------------------------+------------------+
關(guān)閉事件調(diào)度器
通過(guò)命令行
可通過(guò)如下任何一個(gè)命令行
SET GLOBAL event_scheduler = OFF;
SET @@global.event_scheduler = OFF;
SET GLOBAL event_scheduler = 0;
SET @@global.event_scheduler = 0;
通過(guò)配置文件my.cnf
在[mysqld]下增加
event_scheduler = 0 #或者OFF,DISABLED
查看調(diào)度器線(xiàn)程
mysql> show processlist;
+----+------+-----------+------+---------+------+-------+------------------+
| Id | User | Host? ? ? | db? | Command | Time | State | Info? ? ? ? ? ? |
+----+------+-----------+------+---------+------+-------+------------------+
|? 2 | root | localhost | NULL | Query? |? ? 0 | NULL? | show processlist |
+----+------+-----------+------+---------+------+-------+------------------+
查看事件運(yùn)行狀態(tài):
(1)查詢(xún)mysql.event表;
(2)通過(guò)SHOW EVENTS命令;
(4)通過(guò)查詢(xún)information_schema.events表
(5)SHOW CREATE EVENT。 -- 查看創(chuàng)建目錄
總之,event的使用頻率較低建議使用root用戶(hù)進(jìn)行創(chuàng)建和維護(hù)。
使用權(quán)限
單獨(dú)使用event調(diào)用SQL語(yǔ)句時(shí),查看和創(chuàng)建需要用戶(hù)具有event權(quán)限,調(diào)用該SQL語(yǔ)句時(shí),需要用戶(hù)具有執(zhí)行該SQL的權(quán)限。Event權(quán)限的設(shè)置保存在mysql.user表和mysql.db表的Event_priv字段中。
當(dāng)event和procedure配合使用的時(shí)候,查看和創(chuàng)建存儲(chǔ)過(guò)程需要用戶(hù)具有create routine權(quán)限,調(diào)用存儲(chǔ)過(guò)程執(zhí)行時(shí)需要使用excute權(quán)限,存儲(chǔ)過(guò)程調(diào)用具體的SQL語(yǔ)句時(shí),需要用戶(hù)具有執(zhí)行該SQL的權(quán)限。
關(guān)于事件計(jì)劃的權(quán)限:
單獨(dú)使用event調(diào)用SQL語(yǔ)句時(shí),查看和創(chuàng)建需要用戶(hù)具有event權(quán)限,調(diào)用該SQL語(yǔ)句時(shí),需要用戶(hù)具有執(zhí)行該SQL的權(quán)限。Event權(quán)限的設(shè)置保存在mysql.user表和mysql.db表的Event_priv字段中。(FLUSH PRIVILEGES;)
當(dāng)event和procedure配合使用的時(shí)候,查看和創(chuàng)建存儲(chǔ)過(guò)程需要用戶(hù)具有create routine權(quán)限,調(diào)用存儲(chǔ)過(guò)程執(zhí)行時(shí)需要使用excute權(quán)限,存儲(chǔ)過(guò)程調(diào)用具體的SQL語(yǔ)句時(shí),需要用戶(hù)具有執(zhí)行該SQL的權(quán)限。
SELECT HOST,USER,Event_priv FROM mysql.user;
(Figure1:user表的Event_priv權(quán)限)
獲取當(dāng)前登陸的用戶(hù)和數(shù)據(jù)庫(kù):SELECT CURRENT_USER(), SCHEMA();
從Figure1可以知道bfsql@%是沒(méi)有Event_priv權(quán)限的,在該用戶(hù)下創(chuàng)建事件的時(shí)候會(huì)出現(xiàn)下面的錯(cuò)誤:
Error Code: 1044
Access denied for user 'bfsql'@'%' to database 'blog'
如果出現(xiàn)上面的錯(cuò)誤,執(zhí)行下面的SQL就可以給bfsql@%賦予創(chuàng)建Event的權(quán)限:
UPDATE mysql.user SET Event_priv = 'Y' WHERE HOST='%' AND USER='bfsql';
如果你這個(gè)時(shí)候再次執(zhí)行創(chuàng)建Event的SQL,還是會(huì)出現(xiàn)上面的錯(cuò)誤,因?yàn)槟阈枰獔?zhí)行:
FLUSH PRIVILEGES;最后,你可以通過(guò)SHOW GRANTS FOR 'bfsql'@'%';查看所有權(quán)限;
創(chuàng)建event語(yǔ)句相關(guān)命令解釋?zhuān)?/p>
ON SCHEDULE 計(jì)劃任務(wù),有兩種設(shè)定計(jì)劃任務(wù)的方式:
1. AT 時(shí)間戳,用來(lái)完成單次的計(jì)劃任務(wù)。
2. EVERY 時(shí)間(單位)的數(shù)量時(shí)間單位[STARTS 時(shí)間戳] [ENDS時(shí)間戳],用來(lái)完成重復(fù)的計(jì)劃任務(wù)。
在兩種計(jì)劃任務(wù)中,時(shí)間戳可以是任意的TIMESTAMP 和DATETIME 數(shù)據(jù)類(lèi)型,時(shí)間戳需要大于當(dāng)前時(shí)間。
在重復(fù)的計(jì)劃任務(wù)中,時(shí)間(單位)的數(shù)量可以是任意非空(Not Null)的整數(shù)式,時(shí)間單位是關(guān)鍵詞:YEAR,MONTH,DAY,HOUR,MINUTE 或者SECOND。
提示: 其他的時(shí)間單位也是合法的如:QUARTER, WEEK, YEAR_MONTH,DAY_HOUR,DAY_MINUTE,DAY_SECOND,HOUR_MINUTE,HOUR_SECOND, MINUTE_SECOND,不建議使用這些不標(biāo)準(zhǔn)的時(shí)間單位。
標(biāo)注4: [ON COMPLETION [NOT] PRESERVE]
ON COMPLETION參數(shù)表示"當(dāng)這個(gè)事件不會(huì)再發(fā)生的時(shí)候",即當(dāng)單次計(jì)劃任務(wù)執(zhí)行完畢后或當(dāng)重復(fù)性的計(jì)劃任務(wù)執(zhí)行到了ENDS階段。而PRESERVE的作用是使事件在執(zhí)行完畢后不會(huì)被Drop掉,建議使用該參數(shù),以便于查看EVENT具體信息。
標(biāo)注5:[ENABLE | DISABLE]
參數(shù)Enable和Disable表示設(shè)定事件的狀態(tài)。Enable表示系統(tǒng)將執(zhí)行這個(gè)事件。Disable表示系統(tǒng)不執(zhí)行該事件。
可以用如下命令關(guān)閉或開(kāi)啟事件:
ALTER EVENT event_name? ENABLE/DISABLE
標(biāo)注6:[COMMENT 'comment']
注釋會(huì)出現(xiàn)在元數(shù)據(jù)中,它存儲(chǔ)在information_schema表的COMMENT列,最大長(zhǎng)度為64個(gè)字節(jié)。'comment'表示將注釋內(nèi)容放在單引號(hào)之間,建議使用注釋以表達(dá)更全面的信息。
當(dāng)然SQL語(yǔ)句是有限制的,對(duì)它的限制跟函數(shù)Function和觸發(fā)器Trigger 中對(duì)SQL語(yǔ)句的限制是一樣的,如果你在函數(shù)Function 和觸發(fā)器Trigger 中不能使用某些SQL,同樣的在EVENT中也不能使用。明確的來(lái)說(shuō)有下面幾個(gè):
LOCK TABLES
UNLOCK TABLES
CREATE EVENT
ALTER EVENT
LOAD DATA
修改事件 使用ALTER EVENT 來(lái)修改事件,具體的ALTER語(yǔ)法如下,與創(chuàng)建事件的語(yǔ)法類(lèi)似:
刪除事件:EVENT使用DROP EVENT語(yǔ)句來(lái)刪除已經(jīng)創(chuàng)建的事件,語(yǔ)法如下:DROP EVENT [IF EXISTS] event_name
但當(dāng)一個(gè)事件正在運(yùn)行中時(shí),刪除該事件不會(huì)導(dǎo)致事件停止,事件會(huì)執(zhí)行到完畢為止。使用DROP USER和DROP DATABASE 語(yǔ)句同時(shí)會(huì)將包含其中的事件刪除。
每隔一秒自動(dòng)調(diào)用e_test()存儲(chǔ)過(guò)程:
CREATE EVENT IF NOT EXISTS e_test
ON SCHEDULE EVERY 1 SECOND
ON COMPLETION PRESERVE
DO CALL e_test();
每個(gè)月的一號(hào)凌晨1 點(diǎn)執(zhí)行STAT()存儲(chǔ)過(guò)程:
CREATE? EVENT? NOT EXISTS? STAT
ON? SCHEDULE? EVERY? 1? MONTH? STARTS DATE_ADD(DATE_ADD(DATE_SUB(CURDATE(),INTERVAL DAY(CURDATE())-1 DAY), INTERVAL 1 MONTH),INTERVAL 1 HOUR)
ON? COMPLETION? PRESERVE? ENABLE
DO
BEGIN
CALL STAT();
END
創(chuàng)建一個(gè)每隔3秒往test表中插入一條數(shù)據(jù)的事件,代碼如下:
CREATE EVENT IF NOT EXISTS test ON SCHEDULE EVERY 3 SECOND
ON COMPLETION PRESERVE
DO INSERT INTO test(id,t1) VALUES('',NOW());
創(chuàng)建一個(gè)10分鐘后清空test表數(shù)據(jù)的事件
CREATE EVENT IF NOT EXISTS test
ON SCHEDULE
AT CURRENT_TIMESTAMP + INTERVAL 10 MINUTE
DO TRUNCATE TABLE test.aaa;
創(chuàng)建一個(gè)在2012-08-23 00:00:00時(shí)刻清空test表數(shù)據(jù)的事件
CREATE EVENT IF NOT EXISTS test
ON SCHEDULE
AT TIMESTAMP '2012-08-23 00:00:00'
DO TRUNCATE TABLE test;
創(chuàng)建一個(gè)從2012年8月22日21點(diǎn)45分開(kāi)始到10分鐘后結(jié)束,運(yùn)行每隔3秒往test表中插入一條數(shù)據(jù)的事件
CREATE EVENT IF NOT EXISTS test ON SCHEDULE EVERY 3 SECOND
STARTS '2012-08-22 21:49:00'
ENDS '2012-08-22 21:49:00'+ INTERVAL? 10 MINUTE
ON COMPLETION PRESERVE
DO INSERT INTO test(id,t1) VALUES('',NOW());
注意:
默認(rèn)創(chuàng)建事件存儲(chǔ)在當(dāng)前庫(kù)中,也可顯示指定事件創(chuàng)建在哪個(gè)庫(kù)中
通過(guò)show events只能查看當(dāng)前庫(kù)中創(chuàng)建的事件
事件執(zhí)行完即釋放,如立即執(zhí)行事件,執(zhí)行完后,事件便自動(dòng)刪除,多次調(diào)用事件或等待執(zhí)行事件可以查看到。
如果兩個(gè)事件需要在同一時(shí)刻調(diào)用,mysql會(huì)確定調(diào)用他們的順序,如果要指定順序,需要確保一個(gè)事件至少在另一個(gè)事件1秒后執(zhí)行
對(duì)于遞歸調(diào)度的事件,結(jié)束日期不能在開(kāi)始日期之前。
select可以包含在一個(gè)事件中,然而他的結(jié)果消失了,就好像沒(méi)執(zhí)行過(guò)。
刪除事件:drop event 語(yǔ)句刪除它。使用這條語(yǔ)句我們不需要等到最后一次事件調(diào)用。DROP EVENT [IF EXISTS] event_name,drop event if exists event_second;
一個(gè)事件示例:每分鐘的零秒執(zhí)行數(shù)據(jù)遷移
create event updateEachMinuteAt0Second
on schedule every 1 minute starts timestampadd(second,60 -second(current_timestamp()),current_timestamp())
on completion preserve enable
do
begin
call updatetestevent();
end
函數(shù)體內(nèi)使用函數(shù)變量提前聲明 declare a int; ? 判斷是否為空 ? a is null; ?條件塊:if ?body then body; elseif body then body; end if; ? ? ? ? ? ? ? 存儲(chǔ)過(guò)程:begin ?body ?end;