存儲過程接下來會有三篇相關博客html
概述
:簡單的說,就是一組SQL語句集
,功能強大,能夠實現一些比較複雜
的邏輯功能,相似於JAVA語言中的方法;java
說明
:存儲過程跟觸發器有點相似,都是一組SQL集,可是存儲過程是主動調用的,且功能比觸發器更增強大,觸發器是某件事觸發後自動調用。mysql
講存儲過程先講下delimiter命令。咱們都知道sql語句默認都是以分號';'解釋。若是下select * from test_table;sql
這個會有一個問題對於存儲過程:數據庫
CREATE PROCEDURE `proc_if`(IN type int) BEGIN DECLARE c varchar(500); IF type = 0 THEN set c = 'param is 0'; ELSEIF type = 1 THEN set c = 'param is 1'; ELSE set c = 'param is others, not 0 or 1'; END IF; select c; END;
對於上面的存儲過程,它們應該是一個總體,應該是一塊兒執行,而不是遇到分號
就執行。默認狀況下,不可能等到用戶把這些語句所有輸入完以後,再執行整段語句。 由於mysql一遇到分號,它就要自動執行。 即,在語句遇到';'時,mysql解釋器就要執行了。 這種狀況下,就須要事先把delimiter換成其它符號,如//或$$。express
這個時候delimiter
命令就起做用了。服務器
示例函數
# 這路咱們講默認的 ; 結尾改爲 $ 再執行下面語句 DELIMITER $ select * from mall_pro ; select * from member ;
會發現能以前能正常執行的語句這裏報錯了,由於如今修改結尾標誌爲 $
oop
若是咱們改爲:3d
select * from mall_pro $ select * from member $
重點
:delimiter做用域是會話級別的,當你設置了DELIMITER $
那麼在當前會話級別都是變成以$結束。
附一個詳細講delimiter的博客:MySql中 delimiter 詳解
CREATE PROCEDURE 存儲過程名(參數列表) BEGIN # 存儲過程體(一組合法的SQL語句) END
1) 參數列表包含三部分
參數模式 參數名 參數類型
舉例:
in stuname varchar(20)
也能夠寫成stuname varchar(20) 但最好把 in 加上。
2) 參數模式
in:該參數能夠做爲輸入,也就是該參數須要調用方傳入值。 out:該參數能夠做爲輸出,也就是該參數能夠做爲返回值。 inout:該參數既能夠做爲輸入又能夠做爲輸出,也就是該參數既須要傳入值,又能夠返回值。
CALL 存儲過程名(實參列表);
若是存在該存儲過程 則刪除該存儲過程。
drop procedure if exists 存儲過程名稱
重點
:存儲過程體中的每條sql語句的結尾要求必須加分號
。
注意
:若是存儲過程體僅僅只有一句話,begin end能夠省略。
注意
:存儲過程的結尾可使用 delimiter 從新設置(通常若是存儲過程當中存在多個分號結尾,就可使用delimiter)
1)空參列表
# 案例:插入到admin表中五條記錄 DELIMITER $ CREATE PROCEDURE myp1() BEGIN INSERT INTO admin(username,`password`) VALUES('john1','0000'),('lily','0000'),('rose','0000'),('jack','0000'),('tom','0000'); END $ # 調用 CALL myp1()$
2):建立帶in模式參數的存儲過程
## 建立存儲過程實現 根據女神名,查詢對應的男神信息 CREATE PROCEDURE myp2(IN beautyName VARCHAR(20)) BEGIN SELECT bo.* FROM boys bo RIGHT JOIN beauty b ON bo.id = b.boyfriend_id WHERE b.name=beautyName; END $ # 調用 CALL myp2('柳巖')$
注意
:若是傳參帶有中文,若是上面這樣會報字符轉換錯誤,須要將VARCHAR(20)
改爲NVARCHAR(20)
,這個我會將在 Mysql(10)---自定義函數 博客中說明。
3) :建立存儲過程實現,用戶是否登陸成功
CREATE PROCEDURE myp4(IN username VARCHAR(20),IN PASSWORD VARCHAR(20)) BEGIN DECLARE result INT DEFAULT 0;# 聲明並初始化 SELECT COUNT(*) INTO result# 賦值 FROM admin WHERE admin.username = username AND admin.password = PASSWORD; SELECT IF(result>0,'成功','失敗');# 使用 END $ # 調用 CALL myp3('張飛','8888')$
4) 帶有IN 和 OUT 參數
CREATE PROCEDURE myp7(IN beautyName VARCHAR(20),OUT boyName VARCHAR(20),OUT usercp INT) BEGIN SELECT boys.boyname ,boys.usercp INTO boyname,usercp FROM boys RIGHT JOIN beauty b ON b.boyfriend_id = boys.id WHERE b.name=beautyName ; END $ # 調用 CALL myp7('小昭',@name,@cp)$ # 注意OUT的變量必定要是用戶自定義的用戶變量。 SELECT @name,@cp$
5) 建立帶inout模式參數的存儲過程
# 傳入a和b兩個值,最終a和b都翻倍並返回 DELIMITER $ CREATE PROCEDURE myp8(INOUT a INT ,INOUT b INT) BEGIN SET a=a*2; SET b=b*2; END $ # 調用 SET @m=10$ SET @n=20$ CALL myp8(@m,@n)$ # 輸出 20 和 40 SELECT @m,@n$
這裏都是舉了寫簡單的例子,後面會根據實際開發過程寫一個複雜的存儲過程。
咱們知道java對於流程控制有:if、switch。對於Mysql也同樣,它有它本身的流程控制語句,下面咱們一個一個來分析。
1) if函數
語法:if(條件,值1,值2) 功能:實現雙分支 應用在begin end中或外面
2) if結構
# 若是expression爲true 執行 statements IF expression THEN statements; END IF; # 有IF必定要有 END IF # 若是expression爲true 執行 statements 不然執行else-statements IF expression THEN statements; ELSE else-statements; END IF; # 不說了。 IF expression THEN statements; ELSEIF elseif-expression THEN elseif-statements; ... ELSE else-statements; END IF;
重點
:IF結構最後都須要END IF
;結尾。
3)示例
DELIMITER $ CREATE PROCEDURE test_if(score FLOAT) BEGIN DECLARE ch CHAR DEFAULT 'A'; IF score>90 THEN SET ch='A'; ELSEIF score>80 THEN SET ch='B'; ELSEIF score>60 THEN SET ch='C'; ELSE SET ch='D'; END IF; select ch; END $ call test_if(87) #輸出 B
一、語法
#狀況1:相似於switch case 變量或表達式 when 值1 then 語句1; when 值2 then 語句2; ... else 語句n; end #狀況2: case when 條件1 then 語句1; when 條件2 then 語句2; ... else 語句n; end #應用在begin end 中或外面
二、示例
DELIMITER $ CREATE PROCEDURE test_case(in score FLOAT) BEGIN DECLARE ch CHAR DEFAULT 'A'; CASE WHEN score>90 THEN SET ch='A'; WHEN score>80 THEN SET ch='B'; WHEN score>60 THEN SET ch='C'; ELSE SET ch='D'; END CASE; select ch; END $ call test_case(56)$ # 輸出 D
對於java循環結構有:for、while、do-while。而對於mysql則有:while、loop、repeat
。
還有很重要的一點,對於java跳出循環有:continue 和 break。對於mysql也有本身跳出循環命令。
iterate: 相似於 continue,繼續,結束本次循環,繼續下一次 leave: 相似於 break,跳出,結束當前所在的循環 # 至於它們怎麼用,下面會舉例說明
特色
:先判斷後執行。(至關於java中while)
1)語法
【標籤:】while 循環條件 do 循環體; end while【 標籤】; # 當你須要用到 iterate 或者 leave 時就須要用到標籤。若是不須要用到這兩個那麼能夠不須要標籤
2)示例
#案例:1+2+...100 DELIMITER $ drop procedure if exists `pro_while1` $ CREATE PROCEDURE pro_while1(IN insertCount INT) BEGIN DECLARE total INT DEFAULT 0; DECLARE i INT DEFAULT 1; WHILE i<=insertCount DO set total:=total+i; SET i=i+1; END WHILE; select total; END $ # 輸出:5050 CALL pro_while1(100)$
3)帶有leave語句示例
#案例:1+2+...100 DELIMITER $ drop procedure if exists `pro_while1` $ CREATE PROCEDURE pro_while1(IN insertCount INT) BEGIN DECLARE total INT DEFAULT 0; DECLARE i INT DEFAULT 1; a:WHILE i<=insertCount DO IF i=11 THEN LEAVE a; #當i=11是跳出循環 這裏就須要用到標籤了 END IF; set total:=total+i; SET i=i+1; END WHILE a; select total; END $ # 輸出:55 CALL pro_while1(100)$
這裏就用到標籤
(這裏爲a)了。
1) 語法
特色
:先執行後判斷。(至關於Do-while)
【標籤:】repeat 循環體; until 結束循環的條件 end repeat 【標籤】;
2)示例
#案例:1+2+...100 DELIMITER $ drop procedure if exists `pro_while1` $ CREATE PROCEDURE pro_while1(IN insertCount INT) BEGIN DECLARE total INT DEFAULT 0; DECLARE i INT DEFAULT 1; repeat set total:=total+i; SET i=i+1; until i=10 #這裏不須要分號 END repeat; select total; END $ # 輸出:45 CALL pro_while1(100)$
特色
:簡單死循環。(至關於while(true))
1)語法
【標籤:】loop 循環體; end loop 【標籤】;
2) 示例
#案例:1+2+...100 DELIMITER $ drop procedure if exists `pro_while1` $ CREATE PROCEDURE pro_while1(IN insertCount INT) BEGIN DECLARE total INT DEFAULT 0; DECLARE i INT DEFAULT 1; a:loop IF i=11 THEN LEAVE a; END IF; set total:=total+i; SET i=i+1; END loop a; select total; END $ # 輸出:55 CALL pro_while1(100)$
注意
: 有while必定要有 end while。有repeat必定要有end repeat。有loop必定要有end loop。
只要本身變優秀了,其餘的事情纔會跟着好起來(少將9)