存儲過程之流程控制語句


閱讀目錄:通過條件、循環語句,對處理程序進行流程控制

  • 條件控制

    IF條件:條件為真,執行

    CASE條件:匹配到,執行

  • 循環控制

    WHILE循環:先判斷后執行

    REPEAT循環:先執行后判斷

    LOOP循環(死循環)

    LEAVE語句(離開)

    ITERATE語句:迭代,再次循環

    RETURN語句:返回

注意:MySQL不支持FOR循環

 

一、條件控制:if語句、case語句

1、IF語句

IF search_condition_1 THEN statement_list_1
    [ELSEIF search_condition_2 THEN statement_list_2] ...
    [ELSE statement_list_n]
END IF

  如果條件search_condition_1為true,則執行相應的then子句后面的語句列表statement_list_1;

  如果條件search_condition_1不為true,則判斷ELSEIF子句中的條件search_condition_2是否為true,如果為true,則執行相應的then子句后面的語句列表statement_list_2;

  ……

  如果所有的條件都不為true,則執行ELSE子句后面的語句。

例1:創建過程,判斷兩個輸入參數哪一個大

mysql> DELIMITER $$ mysql> CREATE PROCEDURE difference( ->   IN p1 INTEGER, ->   IN p2 INTEGER, ->   OUT p3 INTEGER) -> BEGIN ->   IF p1 > p2 THEN SET p3 = 1; ->     ELSEIF p1= p2 THEN SET p3 = 2; ->     ELSE SET p3 = 3; -> END IF; -> END $$ mysql> DELIMITER ; mysql> call difference(12,56,@ax); mysql> select @ax; +------+
| @ax  |
+------+
|    3 |
+------+

解析:輸入的第一個參數對應p1,第二個對應p2,@ax用來接收輸出變量p3;如果p1>p2,輸出1;如果p1=p2,輸出2;其他情況,輸出3。

例2:創建過程,表示出players表和penalties表哪一個行數更多--->IF條件中允許包含標量子查詢

mysql> create procedure `TENNIS`.`largest`(out t char(10)) -> begin ->   if (select count(*) from PLAYERS)>(select count(*) from PENALTIES) ->   then     ->     set t='PLAYERS'; ->    elseif (select count(*) from PLAYERS)=(select count(*) from PENALTIES) -> then     ->     set t='equal'; ->    else
    ->     set t='PENALTIES'; ->    end if; -> end $$ mysql> delimiter ; mysql> call largest(@lgt); mysql> select @lgt; +---------+
| @lgt    |
+---------+
| PLAYERS |
+---------+

 

2、CASE語句

1)simple case:簡易case語句

CASE case_value
    WHEN when_value THEN statement_list
    [WHEN when_value THEN statement_list] ...
    [ELSE statement_list]
END CASE

case_value是一個表達式,該值和每個when子句中的when_value值進行相等比較

  ①如果和某個when子句中的when_value值相等,則執行相應的then子句后面的語句statement_list;

  ②如果沒有when_value值相等,則執行else子句后面的statement_list。

mysql> DELIMITER $$ mysql> CREATE PROCEDURE p1() -> BEGIN ->   DECLARE v INT DEFAULT 3; ->   CASE v ->       WHEN 2 THEN SELECT v; ->       WHEN 3 THEN SELECT 0; -> ELSE -> BEGIN -> END ->   END CASE; -> END $$ mysql> DELIMITER ; mysql> call p1(); +---+
| 0 |
+---+
| 0 |
+---+

2)searched case:檢索型case語句

CASE
    WHEN search_condition THEN statement_list
    [WHEN search_condition THEN statement_list] ...
    [ELSE statement_list]
END CASE

對於每個when子句,判斷后面的布爾表達式search_condition是否為true

  ①如果某個when子句的條件為true,則執行相應的then子句后面的語句statement_list;

  ②如果所有的when子句的條件都不為true,則執行else后面的語句statement_list。

mysql> DELIMITER $$ mysql> CREATE PROCEDURE p2( -> IN p1 INTEGER, -> IN p2 INTEGER, -> OUT p3 INTEGER) -> BEGIN -> CASE ->          WHEN p1>p2 THEN SET p3=1; ->          WHEN p1=p2 THEN SET p3=2; ->          ELSE SET p3 = 3; -> END CASE; -> END$$ mysql> DELIMITER ; mysql> call p2(123,321,@ax); mysql> select @ax; +------+
| @ax  |
+------+
|    3 |
+------+

注意:

  ①如果在case中,沒有一個when子句的比較結果為true,並且沒有寫else部分,那么就拋出異常:‘Case not found for CASE statement’;

  ②statement_list如果有多條語句,使用begin…end塊包圍起來(復合語句)。

 

 

二、循環控制:while循環、repeat循環、loop循環、leave語句、iterate語句

Tips:循環體結構

  ①條件

  ②SQL語句體

  ③程序體里面需要對條件中的變量進行處理

1、WHILE循環

[begin_label:] WHILE search_condition DO
    statement_list;
END WHILE [end_label];

首先判斷循環開始條件search_condition是否為true(循環結束條件):

  如果為true,則執行循環體中的語句statement_list。每執行完一次,都要重新判斷條件search_condition是否為true;

  如果條件search_condition為false,則循環結束。

特點:

  先判斷,后執行

mysql> DELIMITER $$ mysql> CREATE PROCEDURE do_while(x int) -> BEGIN ->   DECLARE v INT DEFAULT 5; ->   set v=x; ->   WHILE v>0 DO ->     select v; ->     SET v=v-1; ->   END WHILE; -> END$$ mysql> DELIMITER ; mysql> call do_while(2); +------+
|  v   |
+------+
|    2 |
+------+

+------+
|  v   |
+------+
|    1 |
+------+

 

2、REPEAT循環

[begin_label:] REPEAT
    statement_list
UNTIL search_condition
END REPEAT [end_label]

反復執行循環體中的語句statement_list,直到until條件search_condition 為true時,循環結束

特點:

  先執行,后判斷

mysql> DELIMITER $$ mysql> CREATE PROCEDURE dorepeat(p1 INT) -> BEGIN ->   SET @x=0; ->   REPEAT ->     SET @x = @x + 1; ->   UNTIL @x > p1 END REPEAT; -> END$$ mysql> DELIMITER ; mysql> CALL dorepeat(1000); mysql> SELECT @x; +------+
| @x   |
+------+
| 1001 |
+------+

@x:用戶變量,直接使用“set @x=0;”就可以生成這么一個變量,不需要數據類型,在存儲過程里定義的用戶變量,存儲過程外面可以訪問,一直被保存。

 

3、LOOP循環

[begin_label:] LOOP
    statement_list ;
END LOOP [begin_label];

  反復執行循環體中的語句,直到循環結束;

  循環的結束使用leave語句。

例:創建過程,等待指定的秒數后結束

mysql> delimiter $$ mysql> create procedure wait_s(in wait_seconds int) -> begin ->   declare end_time datetime default now() + interval wait_seconds second;  #interval是間隔類型關鍵字     ->   wait_loop:loop ->     if now() > end_time ->     then ->       leave wait_loop;  #leave語句表離開
->     end if; ->   end loop wait_loop; -> end $$ mysql> delimiter ; mysql> call wait_x(10); ……等10秒,結束……

 

4、LEAVE語句

LEAVE  label ;

 作用:用來退出帶標簽的語句塊或者循環

用處:用在 BEGIN ... END中或者循環中 (LOOP, REPEAT, WHILE)

例:創建過程,其中的一個語句塊較早的結束

mysql> DELIMITER $$ mysql> CREATE PROCEDURE small_exit(OUT p1 INTEGER,OUT p2 INTEGER) -> BEGIN ->   SET p1 = 1; ->   SET p2 = 1; ->   block1:BEGIN ->     LEAVE block1; #離開塊block1
->     SET p2 = 3; #已離開,不執行
->   END block1;
->   SET p1 = 4; #執行
-> END$$ mysql> DELIMITER ; mysql> call small_exit(@r1,@r2); mysql> select @r1,@r2; +------+------+ | @r1 | @r2 | +------+------+ | 4 | 1 | +------+------+

 

5、ITERATE語句

ITERATE  label;

只能出現在循環LOOP、REPEAT和WHILE 中(有標簽)

含義:跳出本次循環,開始一次新的循環

mysql> delimiter $$ mysql> CREATE PROCEDURE do_iterate(p1 INT) -> BEGIN ->   label_1: LOOP ->     SET p1 = p1 + 1; ->     IF p1 < 10 THEN ITERATE label_1; #開始下一次循環
->     END IF; ->     LEAVE label_1; ->   END LOOP label_1; ->   SET @x = p1; -> END$$ mysql> delimiter ; mysql> call do_iterate(1); mysql> select @x; +------+ | @x | +------+ | 10 | +------+


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM