Skip to content

17.5 流程控制

在存储程序中使用的流程控制结构可以嵌套使用。

MySQL不支持for循环

注意与MySQL常用函数中的流程函数区分。

1. CASE

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

Or:

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

对于第一种语法,表达式case_valuewhen_value作比较直到有一个相等,不能用于NULL的比较。

对于第二种语法,评估每个search_condition表达式直到有一个为真。

  • 如果没有匹配且没有ELSE语句,会抛出Case not found for CASE statement错误。

  • statement_list不允许为空。

为了忽略空匹配错误,可以在ELSE中写空的BEGIN...END块:

DELIMITER |

CREATE PROCEDURE p()
  BEGIN
    DECLARE v INT DEFAULT 1;

    CASE v
      WHEN 2 THEN SELECT v;
      WHEN 3 THEN SELECT 0;
      ELSE
        BEGIN
        END;
    END CASE;
  END;
  |
DELIMITER ;

2. IF

IF search_condition THEN statement_list
    [ELSEIF search_condition THEN statement_list] ...
    [ELSE statement_list]
END IF;
  • statement_list不允许为空。
  • 每条语句必须以分号;结尾

例子:

MariaDB [MYISAM_TEST]> delimiter //
MariaDB [MYISAM_TEST]> CREATE FUNCTION COMPARE(N INT, M INT) 
RETURNS VARCHAR(50) 
BEGIN 
    DECLARE RE VARCHAR(50);

    IF N > M THEN
        SET RE = CONCAT(N, ' > ', M);
    ELSEIF N < M THEN
        SET RE = CONCAT(N, ' < ', M);
    ELSE
        SET RE = CONCAT(N, ' = ', M);
    END IF;

    RETURN RE;  
END;
//
MariaDB [MYISAM_TEST]> delimiter ;

3. ITERATE

ITERATE label;

LOOP, REPEAT, WHILE语句中使用,意思就是再次开始循环。

4. LEAVE

LEAVE label;

使用范围:BEGIN...END, LOOP, REPEAT, WHILE。用于退出流程控制结构。若label是最外层的存储程序块,意味着退出程序。

5. LOOP

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

通常与LEAVEITERATE配合使用。

6. REPEAT

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

相当于do...while语法。

注意分号

mysql> delimiter //

mysql> CREATE PROCEDURE dorepeat(p1 INT)
       BEGIN
         SET @x = 0;
         REPEAT
           SET @x = @x + 1;
         UNTIL @x > p1 END REPEAT;
       END
       //
Query OK, 0 rows affected (0.00 sec)

mysql> CALL dorepeat(1000)//
Query OK, 0 rows affected (0.00 sec)

mysql> SELECT @x//
+------+
| @x   |
+------+
| 1001 |
+------+
1 row in set (0.00 sec)

7. RETURN

RETURN expr;

只能在函数中使用。

8. WHILE

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