存儲過程
存儲過程是一段代碼,由存儲在一個數據庫的目錄中、聲明式的和過程式的sql語句組成,可以從一個程序、觸發器或者另一個存儲過程調用它從而激活它。
每個存儲過程包含至少3部分:一個參數列表、一個存儲過程、一個名字。
一個數據庫中的存儲過程的名字必須是唯一的,就像表的名字一樣。
一個參數列表可以有0個、1個或多個參數,通過這些參數,過程就可以和外界聯系。
存儲過程支持3中參數類型:
1、輸入參數IN:數據可以傳遞到存儲過程;
2、輸出參數OUT:數據可以由存儲過程傳到外界;
3、輸入輸出參數INOUT:既可以充當輸入參數,也可以充當輸出參數。
就像c語言函數一樣,即使沒有參數,過程名後面還是需要跟一對括號。
存儲過程以begin開始end結束,且之間還可以嵌套begin-end塊。
局部變量:
declare 變量列表 變量類型 [default 默認值]
存儲過程不僅可以使用局部變量,還可以使用全局變量。
默認值不僅限於直接量,還可以是符合表達式,也可以是標量子查詢。
?
1 2 3 4 5 6 7 8 mysql> delimiter // mysql> create procedure test (in a integer) -> begin -> declare b integer default -> (select count(*) from student ); -> end -> // Query OK, 0 rows affected (0.42 sec)set語句
set用於給一個變量賦值。如:
?
1 2 3 set a = 1; set a := 1; set a = 1,b := a;leave語句
離開一個塊(循環塊或者語句塊),類似於break;
如下,進入begin後立即離開。
?
1 2 3 4 mysql> create procedure test (in a integer) -> block : begin -> leave block; -> end//iterate語句
進入一個循環。
call語句
調用存儲過程。
if-esle語句
格式:
if 條件 then 語句 ;
elseif 條件 then 語句;
esle 語句;
end if
?
1 2 3 4 5 6 7 8 9 mysql> create procedure test (in a integer) -> begin -> declare b integer; -> if a < 60 then set b = -1; -> elseif a >60 then set b = 1; -> else set b = 0; -> end if; -> end -> //case語句
格式:
case
when 條件 then 語句;
when 條件 then 語句;
else 語句;
end case;
while 語句
格式:
while 條件 do
語句;
end while;
?
1 2 3 4 5 6 7 mysql> create procedure test (in a integer) -> begin -> declare b integer default 1; -> while b < a do -> set b = b + 1; -> end while; -> end//repeat語句
格式:
repeat
語句;
until 條件 end repeat;
?
1 2 3 4 5 6 7 mysql> create procedure test (in a integer) -> begin -> declare b integer default 1; -> repeat -> set b = b + 1; -> until b > a end repeat; -> end//loop語句
格式:
loop
if或case條件 leave loop;
語句;
end loop;
?
1 2 3 4 5 6 7 8 9 mysql> create procedure test (in a integer) -> begin -> declare b integer default 1; -> loop_block: loop -> if b > a then leave loop_block; -> end if; -> set b = b + 1; -> end loop; -> end//select into 語句
用於將select的查詢結果賦值給過程內的變量。
?
1 2 3 4 mysql> create procedure test (out b integer) -> begin -> select count(*) into b from student; -> end//現在student內有4條數據,調用test如下:
?
1 2 3 4 5 6 7 8 mysql> set @b = 0// mysql> call test(@b)// mysql> select @b// +------+ | @b | +------+ | 4 | +------+如果select語句查詢的結果包含有多行,直接使用into賦值時不可行的。比如:
?
1 2 3 4 mysql> create procedure test (out b integer) -> begin -> select stu_id into b from student; -> end//雖然語法正確,但是在調用時報錯:
?
1 2 mysql> call test(@b)// ERROR 1172 (42000): Result consisted of more than one row怎麼辦?
使用游標訪問多行數據
使用游標涉及到4個語句:
declare cursor(聲明游標)、open cursor、fetch cursor(獲取一行數據)、close cursor。
格式:
declare 游標名字 cursor for 表查詢語句
如下:統計student表有多少行數據。
?
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 mysql> create procedure test (out a integer) -> begin -> declare found boolean default true;--found 用於 判斷是否到最後一行 -> declare b integer; -> declare num cursor for select stu_id from student; --定義游標 -> declare continue handler for not found set found = false; -> set a = 0; -> open num;--打開游標 -> fetch num into b;--讀取一行 -> while found do -> set a = a+1; -> fetch num into b; -> end while; -> close num;--關閉游標 -> end//declare handler語句
存儲過程在執行時可能會出現錯誤,declare handler語句湧來解決當出現錯誤時應該怎麼做。
格式:
declare
<條件>包括:
所以上面的“declare continue handler for not found set found = false;”就是當游標到達行尾是繼續執行過程並且set found = false。
drop 語句
刪除存儲過程;
drop procedure [if exists] 過程名
存儲函數
存儲函數與存儲過程很相似:都是由sql語句和過程式語句所組成的代碼片段,可以從應用程序和sql語句調用。
區別:
1。存儲函數可以擁有輸入參數,但是不能擁有輸出參數。存儲函數本身就是輸出參數。
2.存儲函數的調用和調用熟悉的表兩函數一樣,不能使用一個call語句調用存儲函數。
3.存儲函數必須包含一個return語句。
格式:
create function 函數名(<參數列表>) return 返回類型
begin
函數體;
end
?
1 2 3 4 5 6 7 8 9 10 11 12 mysql> create function dd(ss char(20)) -> returns date -> begin -> return (date(ss)); -> end// mysql> select dd('2012-12-12 12:12:12')// +---------------------------+ | dd('2012-12-12 12:12:12') | +---------------------------+ | 2012-12-12 | +---------------------------+ 1 row in set (0.00 sec)?
1 2 3 4 5 6 7 mysql> select * from student// +------+---------+------+-------+ | name | address | sid | score | +------+---------+------+-------+ | zh | beijing | 1 | 70 | +------+---------+------+-------+ 1 row in set (0.00 sec)?
1 2 3 4 5 mysql> create function dd(id int) -> returns int -> begin return (select score from student where id=id); -> end// Query OK, 0 rows affected (0.00 sec)?
1 2 3 4 5 6 7 mysql> select dd(1)// +-------+ | dd(1) | +-------+ | 70 | +-------+ 1 row in set (0.00 sec)