MySQL(7)---存儲過程

Mysql(7)---存儲過程

存儲過程接下來會有三篇相關博客html

  • 第一篇存儲過程經常使用語法。
  • 第二篇存儲過程當中的遊標。
  • 第三篇單獨講一個實際開發過程當中複雜的真實的案例。

1、概述

一、什麼是存儲過程

概述:簡單的說,就是一組SQL語句集,功能強大,能夠實現一些比較複雜的邏輯功能,相似於JAVA語言中的方法;java

說明 :存儲過程跟觸發器有點相似,都是一組SQL集,可是存儲過程是主動調用的,且功能比觸發器更增強大,觸發器是某件事觸發後自動調用。mysql

二、優勢

  • 提升代碼的重用性
  • 簡化操做
  • 減小了編譯次數而且減小了和數據庫服務器的鏈接次數,提升了效率

2、delimiter命令

講存儲過程先講下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 詳解


3、存儲過程語法

一、建立

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$

這裏都是舉了寫簡單的例子,後面會根據實際開發過程寫一個複雜的存儲過程。


3、流程控制結構

咱們知道java對於流程控制有:if、switch。對於Mysql也同樣,它有它本身的流程控制語句,下面咱們一個一個來分析。

一、IF語句

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

2.case結構

一、語法

#狀況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


5、循環結構

對於java循環結構有:for、while、do-while。而對於mysql則有:while、loop、repeat

還有很重要的一點,對於java跳出循環有:continue 和 break。對於mysql也有本身跳出循環命令。

iterate: 相似於 continue,繼續,結束本次循環,繼續下一次
leave:   相似於  break,跳出,結束當前所在的循環
# 至於它們怎麼用,下面會舉例說明

1.while

特色:先判斷後執行。(至關於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)了。

二、repeat

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)$

三、loop

特色:簡單死循環。(至關於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)
相關文章
相關標籤/搜索