我們把若干條 SQL 封裝起來,起個名字,就叫過程,把此過程存儲在數據庫中就叫存儲過程。
過程:沒有返回值的函數;
函數:有返回值的過程。
1、創建語法
create procedure p_name(in name, out age)
begin
...
end;
參數類型:
(1) in 表示只是用來輸入;
(2) out 表示只是用來輸出;
(3) inout 可以用來輸入,也可以用作輸出。
調用存儲過程:
call p_name('shang', @age);
2、查詢存儲過程
show procedure status like 'p_name';
show create procedure p_name \G
select * from information_schema.routines where routine_name = 'p1';
3、刪除存儲過程
drop procedure [if exists] p_name; #刪除存儲過程需要確保有 alter routine 的相應權限
變量定義:declare var1 [,var2...] var_type [default 默認值];
流程控制:if、case、loop、leave、iterate、repeat、while
總結
優點:
1、執行速度快。因為我們的每個 SQL 語句都需要經過編譯,然后再運行,但是存儲過程都是直接編譯好了之后,直接運行即可;
2、減少網絡流量。我們傳輸一個存儲過程比我們傳輸大量的 SQL 語句的開銷要小得多;
3、提高系統安全性。因為存儲過程可以使用權限控制,而且參數化的存儲過程可以有效地防止 SQL 注入攻擊。保證了其安全性;
4、耦合性降低。當我們的表結構發生了調整或變動之后,我們可以修改相應的存儲過程,我們的應用程序在一定程度上需要改動的地方就較小了;
5、重用性強。因為我們寫好一個存儲過程之后,再次調用它只需要一個名稱即可,也就是“一次編寫,隨處調用”,而且使用存儲過程也可以讓程序的模塊化加強。
缺點:
1、移植性差。因為存儲過程是和數據庫綁定的,如果我們要更換數據庫之類的操作,可能很多地方需要改動;
2、修改不方便。因為對于存儲過程而言,我們并不能特別有效的調試,它的一些 bug 可能發現的更晚一些,增加了應用的危險性;
3、優勢不明顯和贅余功能。對于小型 web 應用來說,如果我們使用語句緩存,發現編譯 SQL 的開銷并不大,但是使用存儲過程卻需要檢查權限一類的開銷,這些贅余功能也會在一定程度上拖累性能。
實例:
create procedure p2()
begin
declare total int default 0;
declare num int default 0;
while num <= 100 do
set total := total + num;
set num := num +1;
end while;
select total;
end$
create procedure p3(in n int)
begin
declare total int default 0;
declare num int default 0;
while num <= n do
set total := total + num;
set num := num +1;
end while;
select total;
end$
create procedure p5(in n int,out total int)
begin
declare num int default 0;
set total := 0;
while num <= n do
set total := total + num;
set num := num +1;
end while;
end$
create procedure p6(inout age int)
begin
set age := age + 10;
end$
set @curr_age = 14$
call p6(@curr_age)$
select @curr_age$