存儲過程和函數(shù)相對于java的函數(shù)的是非常類似的语稠,把語句組合到一起脚草,使用的時候,直接調(diào)用就可以了披坏。
存儲過程
語法
CREATE PROCEDURE sp_name ([proc_parameter[,...]])
[characteristic ...] routine_body
routine_body是主語部分慈参,填寫上代碼,可以是一條語句刮萌,也可以是復合語句驮配。復合語句必須加上begin end,代碼寫在begin end中。
參數(shù)類型
參數(shù)類型壮锻,分為三種 IN琐旁,OUT,INOUT猜绣;
- IN 默認模式灰殴。表示參數(shù)必須傳遞給存儲過程,且是不能修改的掰邢,只讀牺陶;
- OUT表示參數(shù)可以改變,并將其更改后新值傳遞會調(diào)用程序辣之。請注意:存儲過程在啟動時無法訪問OUT參數(shù)的初始值掰伸;
- INOUT是IN和OUT的組合。調(diào)用程序可以傳遞參數(shù)怀估,并且存儲過程可以修改INOUT參數(shù)并將新值傳遞回調(diào)用程序
create procedure(IN a INT, OUT b INT, INOUT c INT)
....
定義變量
DECLARE variable_name datatype(size) DEFAULT default_value;
- DECLARE 關鍵字后面跟變量名狮鸭。
- 聲明變量之后,它的初始值為NULL,可以設置默認值
可以同時聲明多個變量
DECLARE x, y INT DEFAULT 0;
聲明了兩個整數(shù)變量x和y多搀,默認值為0
分配變量值
有兩種方式可以修改變量值歧蕉,一種是set語法
一種是select ... into ...語法
DECLARE X INT DEFAULT 0;
SET X = 1;
SELECT COUNT(*) INTO X FROM E;
上面的語句,先用的set語法將X的值改為1康铭,然后將E表中的記錄條數(shù)賦值給X惯退。
注意:SET X = 1和 SET X := 1是一樣的效果;select into 必須只能查出一行結(jié)果从藤,多個會報錯蒸痹。
流程控制
IF
IF expression THEN
statements;
ELSEIF expression THEN
statements;
ELSE statements;
END IF;
和高級語言中的if結(jié)構(gòu)非常類似
CASE
簡單的case語句
CASE expression
WHEN expression1 THEN commands
WHEN expression2 THEN commands
...
ELSE commands
END
這種的簡單的case語句可以用于任何地方。
如果作為控制語句的話呛哟,格式如下:
CASE expression
WHEN expression1 THEN statements;
WHEN expression2 THEN statements;
...
ELSE statements;
END CASE;
這種case語句只能用于begin end中(注意兩者之間的差別)
循環(huán)
mysql中有三種循環(huán)語句 WHILE, REPEAT和LOOP
while
[name:] WHILE expression DO
statments;
END WHILE
expression 為真叠荠,則執(zhí)行循環(huán);name是該循環(huán)的名稱,是可選的扫责。
repeat和loop
[name:]REPEAT
statements;
UNTIL expression
END REPEAT
[name:LOOP
statements;
END REPEAT
loop沒有退出條件榛鼎。
最好和LEAVE和ITERATE語句一起使用
LEAVE語句和break作用一樣,直接跳出循環(huán)鳖孤。
ITERATE和continue作用一樣者娱,結(jié)束本次循環(huán)。
LEAVE和ITERATE使用苏揣,循環(huán)必須要名字黄鳍。
如:
[name:] WHILE expression DO
statments;
IF expression2 THEN LEAVEN name;
END IF;
END WHILE;
異常處理
發(fā)生異常時,我們可以聲明一個處理程序
DECLARE action HANDLER FOR condition_value statement;
action 接受以下值之一:
- CONTINUE:繼續(xù)執(zhí)行封閉代碼塊(begin end)
- EXIT:封閉代碼塊的執(zhí)行終止
condition_value指定一個特定條件或一類激活處理程序的條件平匈。condition_value接受以下值: - 一個mysql錯誤代碼
- 標準的sqlstate值或者它可以是 SQL WARNING, NOT FOUND或SQL EXCEPTION條件框沟。NOT FOUND 用于游標或select into variable_list語句藏古。
游標
要處理存儲過程中的結(jié)果集,就需要使用游標了忍燥。游標可以迭代查詢返回的一組行拧晕。
游標是只讀的。
游標使用的步驟如下:
聲明游標
DECLAERE cursor_name CURSOR FOR SELECT_statements;
游標必須聲明在變量聲明之后梅垄。否則會報錯厂捞。游標必須始終與select語句相關聯(lián)。
打開游標
open cursor_name;
取數(shù)據(jù)
FETCHC cursor_name INTO variables list;
將游標中的值取出來队丝,并賦值給variables list靡馁。
關閉游標
close cursor_name;
示例:
delimiter //
create procedure mypr()
begin
declare i int default 0;
declare is_finished int default 0;
declare cur cursor for select id from a;
declare continue handler for not found set is_finished = 1;
open cur;
while is_finished = 0 do
fetch cur into i;
if is_finished = 0 then select i;
end if;
end while;
close cur;
end //
delimiter ;
上述示例沒有什么業(yè)務場景,就是一個簡單的打印a表中所有的id值机久。
函數(shù)
函數(shù)和存儲過程十分的類似臭墨。
其創(chuàng)建的語句為:
CREATE FUNCTION function_name(param1,param2,…)
RETURNS datatype
[NOT] DETERMINISTIC
statements
- 創(chuàng)建函數(shù)關鍵字是FUNCTION,參數(shù)不能IN,OUT,INOUT修飾。
- RETURNS語句中必須指定返回值的數(shù)據(jù)類型吞加。
- 對于相同的輸入?yún)?shù),如果函數(shù)返回相同的結(jié)果尽狠,這樣則被認為是確定性的衔憨,否則不是確定性的。必須決定一個存儲函數(shù)是否是確定性的袄膏。如果聲明不正確践图,可能產(chǎn)生意想不到的結(jié)果。
- 將代碼寫入主體中弱贼⌒芫可以使單個語句也可以是復合語句冀痕。在主語部分中,必須至少指定一個RETURN語句揖盘,return返回一個值給調(diào)用者。
示例:
delimiter //
create function myfu(a int) return varchar(20)
begin
declare v varchar(20) default '';
case a
when 1 then set v = 'hello';
when 2 then set v = 'world';
else v = 'nihao';
end case;
return v;
end //
delimiter ;
區(qū)別
存儲過程參數(shù)有IN,OUT,INOUT三種锌奴,而函數(shù)中參數(shù)沒有類型修飾兽狭,均為IN參數(shù)
存儲過程沒有返回值(可以通過OUT或INOUT參數(shù)返回值),而函數(shù)有返回值
調(diào)用方式不同鹿蜀,存儲過程用call調(diào)用箕慧,而函數(shù)使用select調(diào)用(和系統(tǒng)函數(shù)一致)