存儲過程和自定義函數是事先通過編譯並存儲在數據庫中的一段SQL語句的集合。相對普通查詢優勢:html
存儲過程與函數的區別在於函數必須有返回值,而存儲過程沒有,存儲過程的參數可使用in(輸入),out(輸出),inout(輸入輸出),而函數的參數只能是in類型。mysql
建立、修改、調用 存儲過程或函數sql
#建立存儲過程
create procedure sp_name([proc_paramenter[,...]])
[characteristic ...] routine_body
#proc_parameter: [in|out|inout] param_name type
#type:任何可用的MySQL數據類型
#routine_body:是SQL代碼的內容,能夠用BEGIN...END來表示SQL代碼的開始和結束。
___________________________________________________
#建立函數
create function sp_name([func_parameter[,...]])
return type
[characteristic ...]routine_body
___________________________________________________
#修改存儲過程或函數
alter {procedure|function} sp_name [characteristic ...]
___________________________________________________
#調用過程的語句
call sp_name([parameter[,...]]);
___________________________________________________
#刪除存儲過程或函數
drop {procedure|function} [if exists] sp_name;
___________________________________________________
#查看存儲過程或函數狀態
show {procedure|function} status like 'sp_name';
___________________________________________________
#查看存儲過程或函數的定義
show create {procedure|function} sp_name;複製代碼
其中characteristic的取值爲:數據庫
值 | 說明 |
---|---|
language sql | 說明routine_body部分是由SQL語句組成的,當前系統支持的語言爲SQL |
[not] deterministic | 指明存儲過程執行的結果是否肯定。DETERMINISTIC 表示結果是肯定的。每次執行存儲過程時,相同的輸入會獲得相同的輸出。 |
{contains sql \no sql \ reads sql data \modifies sql data} | 指明子程序使用SQL語句的限制。CONTAINS SQL代表子程序包含SQL語句,可是不包含讀寫數據的語句;NO SQL代表子程序不包含SQL語句;READS SQL DATA:說明子程序包含讀數據的語句;MODIFIES SQL DATA代表子程序包含寫數據的語句。默認狀況下,系統會指定爲CONTAINS SQL。 |
sql_security{definer\invoker} | 指明誰有權限來執行。DEFINER 表示只有定義者才能執行;INVOKER 表示擁有權限的調用者能夠執行。默認狀況下,系統指定爲DEFINER。 |
comment 'string' | 註釋信息,能夠用來描述存儲過程或函數 |
MySQL的存儲過程或函數中容許包含DDL語句,也容許存儲過程當中執行事務處理。存儲過程和函數中能夠調用其餘的過程或函數。安全
舉例說明:服務器
delimiter //
create procedure procedure_test(
in v_min int,in v_max int,out num int)
reads sql data
begin
#查詢出test1表中sid在v_min 和v_max之間的記錄
select * from test1
where sid > v_min and sid < v_max;
#將返回的記錄行數寫入num變量中輸出
select found_rows() into num;
end //
delimiter ;複製代碼
注意:「DELIMITER //」語句的做用是將MYSQL的結束符設置爲//,由於MYSQL默認的語句結束符爲分號;,爲了不與存儲過程當中SQL語句結束符相沖突,須要使用DELIMITER 改變存儲過程的結束符,並以「END //」結束存儲過程。函數
存儲過程定義完畢以後再使用DELIMITER ;恢復默認結束符。DELIMITER 也能夠指定其餘符號爲結束符
建立的存儲過程及test1數據
ui
變量的做用範圍只能在begin...end塊中,能夠用在嵌套中。變量的定義必須寫在複合語句的開頭,而且在任何其餘語句的前面。能夠一次聲明多個相同類型的變量。
(10)mysql中的變量-參考連接spa
#建立一個函數返回v_min、v_max之間的sid之和。
delimiter //
create function function_test
(v_min int,v_max int)
returns int
reads sql data
begin
declare temp int;
select sum(sid) into @temp
from test1
where sid > v_min and sid < v_max;
return @temp
end //
delimiter ;複製代碼
建立結果:
.net
條件定義和處理能夠用來定義在處理過程當中遇到問題(錯誤,警告,異常)時的處理步驟。條件處理程序定義參見連接以下:
(11)mysql中的條件定義、處理-參考連接
delimiter $
create procedure pro_condition()
begin
set @x=1;
select * from test111;
set @x=2;
end$
delimiter ;複製代碼
結果
drop procedure if exists pro_condition;
delimiter $
create procedure pro_condition()
begin
declare continue handler for 1146 set @x2=1;
set @x=1;
select * from test111;
set @x=2;
end$
delimiter ;複製代碼
結果:
在存儲過程當中可使用光標對結果集進行循環處理。光標使用參看連接以下:
(12)mysql中的光標-參考連接
DELIMITER $
CREATE PROCEDURE pro_cursor()
BEGIN
DECLARE sid_i INT;
DECLARE cur_test CURSOR FOR SELECT sid FROM test1;
DECLARE EXIT HANDLER FOR NOT FOUND CLOSE cur_test;
SET @x1=0;
SET @x2=0;
OPEN cur_test;
REPEAT
FETCH cur_test INTO sid_i;
SET @x1=@x1+sid_i;
SET @x2=@x2+1;
UNTIL 0 END REPEAT;
CLOSE cur_test;
END $
DELIMITER ;
#查看結果
call pro_cursor();
select @x1,@x2;複製代碼
test1表結構及數據
存儲過程和函數中可使用流程控制來控制語句的執行。MySQL 中可使用IF 語句、CASE 語句、LOOP語句、LEAVE 語句、ITERATE 語句、REPEAT 語句和WHILE 語句來進行流程控制。具體流程使用參見以下連接:
(13)mysql中的流程控制-參考連接
delimiter $
create procedure pro_flow_control(in sid_v int)
begin
if sid_v > 5 then
select * from test1 where sid>5;
else
select * from test1 where sid<=5;
end if;
end $
delimiter ;複製代碼
結果: