存儲過程是一組爲了完成某項特定功能的sql語句集,其實質上就是一段存儲在數據庫中的代碼,他能夠由聲明式的sql語句(如CREATE,UPDATE,SELECT等語句)和過程式sql語句(如IF...THEN...ELSE控制結構語句)組成。存儲過程思想上很簡單,就是數據庫 SQL 語言層面的代碼封裝與重用。html
優勢:mysql
缺點:
存儲過程,每每定製化於特定的數據庫上,由於支持的編程語言不一樣。當切換到其餘廠商的數據庫系統時,須要重寫原有的存儲過程。sql
在sql中服務器處理sql語句默認是以分號做爲語句的結束標誌,然而在建立存儲過程時,存儲過程體中可能包含多條sql語句,這些sql語句若是仍以分號做爲語句結束符,那麼服務器在處理時會以第一條sql語句處的分號做爲整個程序的結束符,而再也不去處理後面的sql。
爲解決這個問題,一般使用DELIMITER命令,將sql語句的結束符臨時修改成其餘符號。
DELIMITER語法格式:數據庫
DELIMITER $$
複製代碼
$$
是用戶定義的結束符,一般這個符號能夠是一些特殊的符號。另外應避免使用反斜槓,由於他是轉義字符。 若但願換回默認的分號做爲結束標記,只需再在命令行輸入下面的sql語句便可。編程
DELIMITER ;
複製代碼
在Mysql中,使用CREATE PROCEDURE
語句來建立存儲過程。bash
CREATE PROCEDURE p_name([proc_parameter[,...]])
routine_body
複製代碼
其中,語法項「proc_parameter」的語法格式是:服務器
[IN|OUT|INOUT]parame_name type
複製代碼
IN
,輸出參數OUT
,輸入輸出參數INOUT
。輸入參數是使數據能夠傳遞給一個存儲過程;輸出參數是用於存儲過程須要返回的一個操做結果;輸入輸出參數既能夠充當輸入參數也能夠充當輸出結果。BEGIN
開始,以關鍵字END
結束。若只有一條sql能夠忽略BEGIN....END
標誌。在存儲過程體中能夠聲明局部變量,用來存儲過程體中的臨時結果。在Mysql中使用DECLARE
語句來聲明局部變量。編程語言
DECLARE var_name type [DEFAULT value]
複製代碼
"var_name"用於指定局部變量的名稱;"type"用來聲明變量的類型;"DEFAULT"用來指定默認值,若是沒有指定則爲NULL。函數
注意:局部變量只能在存儲過程體的BEGIN...END語句塊中;局部變量必須在存儲過程體的開頭處聲明;局部變量的做用範圍僅限於聲明它的BEGIN...END語句塊,其餘語句塊中的語句不可使用它。oop
用戶變量通常以@開頭。
注意:濫用用戶變量會致使程序難以理解及管理。
在Mysql中經過SET語句對局部變量賦值,其格式是:
SET var_name = expr[,var_name2 = expr]....
複製代碼
在Mysql中,可使用SELECT...INTO語句把選定的列的值存儲到局部變量中。格式是:
SELECT col_name[,..] INTO var_name[,....] table_expr
複製代碼
其中"col_name"用於指定列名;"var_name"用於指定要賦值的變量名;"table_expr"表示SELECT語句中FROM後面的部分。
注意:SELECT...INTO語句返回的結果集只能有一行數據。
mysql > DELIMITER &&
mysql > CREATE PROCEDURE proc2(IN parameter int)
-> begin
-> declare var int;
-> set var=parameter+1;
-> if var=0 then
-> insert into t values(17);
-> end if;
-> if parameter=0 then
-> update t set s1=s1+1;
-> else
-> update t set s1=s1+2;
-> end if;
-> end;
-> &&
mysql > DELIMITER ;
複製代碼
case語句:
mysql > DELIMITER &&
mysql > CREATE PROCEDURE proc3 (in parameter int)
-> begin
-> declare var int;
-> set var=parameter+1;
-> case var
-> when 0 then
-> insert into t values(17);
-> when 1 then
-> insert into t values(18);
-> else
-> insert into t values(19);
-> end case;
-> end;
-> &&
mysql > DELIMITER ;
複製代碼
mysql > DELIMITER &&
mysql > CREATE PROCEDURE proc4()
-> begin
-> declare var int;
-> set var=0;
-> while var<6 do
-> insert into t values(var);
-> set var=var+1;
-> end while;
-> end;
-> &&
mysql > DELIMITER ;
複製代碼
repeat···· end repea:
它在執行操做後檢查結果,而 while 則是執行前進行檢查。
mysql > DELIMITER &&
mysql > CREATE PROCEDURE proc5 ()
-> begin
-> declare v int;
-> set v=0;
-> repeat
-> insert into t values(v);
-> set v=v+1;
-> until v>=5
-> end repeat;
-> end;
-> &&
mysql > DELIMITER ;
複製代碼
repeat
--循環體
until 循環條件
end repeat;
複製代碼
loop ·····endloop:
loop 循環不須要初始條件,這點和 while 循環類似,同時和 repeat 循環同樣不須要結束條件, leave 語句的意義是離開循環。
mysql > DELIMITER &&
mysql > CREATE PROCEDURE proc6 ()
-> begin
-> declare v int;
-> set v=0;
-> LOOP_LABLE:loop
-> insert into t values(v);
-> set v=v+1;
-> if v >=5 then
-> leave LOOP_LABLE;
-> end if;
-> end loop;
-> end;
-> &&
mysql > DELIMITER ;
複製代碼
ITERATE迭代:
mysql > DELIMITER &&
mysql > CREATE PROCEDURE proc10 ()
-> begin
-> declare v int;
-> set v=0;
-> LOOP_LABLE:loop
-> if v=3 then
-> set v=v+1;
-> ITERATE LOOP_LABLE;
-> end if;
-> insert into t values(v);
-> set v=v+1;
-> if v>=5 then
-> leave LOOP_LABLE;
-> end if;
-> end loop;
-> end;
-> &&
mysql > DELIMITER ;
複製代碼
MySQL中的遊標能夠理解成一個可迭代對象(類比Python中的列表、字典等可迭代對象),它能夠用來存儲select 語句查詢到的結果集,這個結果集能夠包含多行數據,從而使咱們可使用迭代的方法從遊標中依次取出每行數據。
MySQL遊標的特色:
1.只讀:沒法經過光標更新基礎表中的數據。
2.不可滾動:只能按照select語句肯定的順序獲取行。不能以相反的順序獲取行。 此外,不能跳過行或跳轉到結果集中的特定行。
3.敏感:有兩種遊標:敏感遊標和不敏感遊標。敏感遊標指向實際數據,不敏感遊標使用數據的臨時副本。敏感遊標比一個不敏感的遊標執行得更快,由於它不須要臨時拷貝數據。MySQL遊標是敏感的。
declare cursor_name cursor for select_statement;
複製代碼
open cursor_name;
複製代碼
fetch cursor_name into var_name;
複製代碼
close cursor_name;
複製代碼
當遊標再也不使用時,應該關閉它。 當使用MySQL遊標時,還必須聲明一個notfound處理程序來處理當遊標找不到任何行時的狀況。 由於每次調用fetch語句時,遊標會嘗試依次讀取結果集中的每一行數據。 當遊標到達結果集的末尾時,它將沒法得到數據,而且會產生一個條件。 處理程序用於處理這種狀況。
declare continue handler for not found set type = 1;
複製代碼
type是一個變量,示遊標到達結果集的結尾。
delimiter $$
create PROCEDURE phoneDeal()
BEGIN
DECLARE id varchar(64); -- id
DECLARE phone1 varchar(16); -- phone
DECLARE password1 varchar(32); -- 密碼
DECLARE name1 varchar(64); -- id
-- 遍歷數據結束標誌
DECLARE done INT DEFAULT FALSE;
-- 遊標
DECLARE cur_account CURSOR FOR select phone,password,name from account_temp;
-- 將結束標誌綁定到遊標
DECLARE CONTINUE HANDLER FOR NOT FOUND SET done = TRUE;
-- 打開遊標
OPEN cur_account;
-- 遍歷
read_loop: LOOP
-- 取值 取多個字段
FETCH NEXT from cur_account INTO phone1,password1,name1;
IF done THEN
LEAVE read_loop;
END IF;
-- 你本身想作的操做
insert into account(id,phone,password,name) value(UUID(),phone1,password1,CONCAT(name1,'的家長'));
END LOOP;
-- 關閉遊標
CLOSE cur_account;
END $$
複製代碼
使用call語句調用存儲過程
call sp_name[(傳參)];
複製代碼
使用drop語句刪除存儲過程
DROP PROCEDURE sp_name
複製代碼
存儲函數和存儲過程同樣,都是sql和語句組成的代碼塊。
存儲函數不能有輸入參數,而且能夠直接調用,不須要call語句,且必須有一條包含RETURN語句。
在Mysql中使用CREATE FUNCTION語句建立:
CREATE FUNCTION fun_name (par_name type[,...])
RETURNS type
[characteristics]
fun_body
複製代碼
其中,fun_name爲函數名,而且名字惟一,不能與存儲過程重名。par_name是指定的參數,type爲參數類型;RETURNS字句用來聲明返回值和返回值類型。fun_body是函數體,全部存儲過程當中的sql在存儲函數中一樣可使用。可是存儲函數體中必須包含一個RETURN 語句。
characteristics指定存儲過程的特性,有如下取值:
delimiter $$
create function getAnimalName(animalId int) RETURNS VARCHAR(50)
DETERMINISTIC
begin
declare name VARCHAR(50);
set name=(select name from animal where id=animalId);
return (name);
end$$
delimiter;
-- 調用
select getAnimalName(4)
複製代碼
其餘參考:
www.cnblogs.com/zhanglei93/… www.cnblogs.com/lyhabc/p/37… blog.csdn.net/yuefeicall/…