mysql 存儲(chǔ)過(guò)程和事件總結(jié)

任務(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;

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • 當(dāng)一個(gè)大型系統(tǒng)在建立時(shí),會(huì)發(fā)現(xiàn),很多的SQL操作是有重疊的,個(gè)別計(jì)算是相同的,比如:業(yè)務(wù)系統(tǒng)中,計(jì)算一張工單的計(jì)算...
    JackFrost_fuzhu閱讀 3,524評(píng)論 0 27
  • 1. Java基礎(chǔ)部分 基礎(chǔ)部分的順序:基本語(yǔ)法,類(lèi)相關(guān)的語(yǔ)法,內(nèi)部類(lèi)的語(yǔ)法,繼承相關(guān)的語(yǔ)法,異常的語(yǔ)法,線(xiàn)程的語(yǔ)...
    子非魚(yú)_t_閱讀 34,853評(píng)論 18 399
  • 轉(zhuǎn)載自這里 存儲(chǔ)過(guò)程簡(jiǎn)介 我們常用的操作數(shù)據(jù)庫(kù)語(yǔ)言SQL語(yǔ)句在執(zhí)行的時(shí)候需要要先編譯,然后執(zhí)行,而存儲(chǔ)過(guò)程(Sto...
    杜七閱讀 2,477評(píng)論 4 27
  • 定義函數(shù)的方式有兩種:一種是函數(shù)聲明,另一種是函數(shù)表達(dá)式。函數(shù)聲明的語(yǔ)法是這樣的。 說(shuō)明:Firefox、Safa...
    yjaal閱讀 262評(píng)論 0 1
  • (1) 昨天晚間忽然偏頭痛發(fā)作。許是著了涼,也可能是拿手機(jī)看書(shū)刺激了眼神經(jīng)。以前辦公室內(nèi)空氣不流通時(shí)也會(huì)引發(fā)??傊?..
    Asura_Shi閱讀 292評(píng)論 0 0

友情鏈接更多精彩內(nèi)容