流程控制语句

 CASE语句

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

对于第一种语法,case_value是一个表达式。将该值与when_value每个WHEN子句中表达式进行 比较, 直到其中一个相等为止。when_value找到相等时,将执行相应的THEN子句 statement_list如果不 when_value等于,则执行该 ELSE子句 statement_list(如果存在)。

NULL由于NULL = NULL 为false 因此无法使用此语法测试是否相等 

每个都statement_list包含一个或多个SQL语句;statement_list不允许为空 

要处理任何WHEN子句都没有值匹配的情况 ,请使用ELSE 包含一个空 BEGIN ... END块的,如本示例所示。(该ELSE条款中此处使用的缩进仅出于清楚目的,在其他方面并不重要。)

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;
  |

IF语句

IF search_condition THEN statement_list
    [ELSEIF search_condition THEN statement_list] ...
    [ELSE statement_list]
END IF

每个都statement_list包含一个或多个SQL语句;statement_list不允许为空 。

IF ... END IF就像存储程序中使用的所有其他流控制块一样, 一个块必须以分号终止,如下例所示:

DELIMITER //

CREATE FUNCTION SimpleCompare(n INT, m INT)
  RETURNS VARCHAR(20)

  BEGIN
    DECLARE s VARCHAR(20);

    IF n > m THEN SET s = '>';
    ELSEIF n = m THEN SET s = '=';
    ELSE SET s = '<';
    END IF;

    SET s = CONCAT(n, ' ', s, ' ', m);

    RETURN s;
  END //

DELIMITER ;

与其他流控制构造一样,IF ... END IF块可以嵌套在其他流控制构造中,包括其他IF 语句。每一个都IF必须以自己的名称结尾,END IF后跟一个分号。您可以使用缩进使人类更容易阅读嵌套的流控制块(尽管MySQL不需要),如下所示:

DELIMITER //

CREATE FUNCTION VerboseCompare (n INT, m INT)
  RETURNS VARCHAR(50)

  BEGIN
    DECLARE s VARCHAR(50);

    IF n = m THEN SET s = 'equals';
    ELSE
      IF n > m THEN SET s = 'greater';
      ELSE SET s = 'less';
      END IF;

      SET s = CONCAT('is ', s, ' than');
    END IF;

    SET s = CONCAT(n, ' ', s, ' ', m, '.');

    RETURN s;
  END //

DELIMITER ;

 

ITERATE

ITERATE label

ITERATE只能出现 LOOP, REPEAT和 WHILE语句。 ITERATE表示“ 再次开始循环。”

 LEAVE声明

LEAVE label

该语句用于退出具有给定标签的流控制构造。如果标签用于最外面存储的程序块,则LEAVE退出程序。

LEAVE can be used within BEGIN ... END or loop constructs (LOOPREPEATWHILE).

 LOOP Statement

[begin_label:] LOOP
    statement_list
END LOOP [end_label]

LOOP实现了一个简单的循环结构,从而允许重复执行语句列表,该语句列表由一个或多个语句组成,每个;语句均以分号()语句定界符终止重复循环中的语句,直到循环终止。通常,这是通过LEAVE声明来完成的 在存储的函数中,RETURN也可以使用它完全退出该函数。

忽略包含循环终止语句会导致无限循环。

CREATE PROCEDURE doiterate(p1 INT)
BEGIN
  label1: LOOP
    SET p1 = p1 + 1;
    IF p1 < 10 THEN
      ITERATE label1;
    END IF;
    LEAVE label1;
  END LOOP label1;
  SET @x = p1;
END;

REPEAT语句

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

REPEAT重复 语句中的语句列表, 直到search_condition表达式为真为止因此,a REPEAT总是至少进入一次循环。 statement_list由一个或多个语句组成,每个语句以分号(;)语句定界符终止

 

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)

 RETURN语句

RETURN expr

RETURN语句终止存储函数的执行,并将该值返回 expr给函数调用者。RETURN 存储的函数中必须至少有一个语句。如果函数具有多个退出点,则可能有多个。

在存储过程,触发器或事件中不使用此语句。LEAVE语句可用于退出那些类型的存储程序。

 WHILE陈述式

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

WHILE 只要search_condition表达式为真,就会重复 语句中的语句列表。 statement_list由一个或多个SQL语句组成,每个语句以分号(;)语句定界符终止

WHILE可以标记 一个声明。

CREATE PROCEDURE dowhile()
BEGIN
  DECLARE v1 INT DEFAULT 5;

  WHILE v1 > 0 DO
    ...
    SET v1 = v1 - 1;
  END WHILE;
END;

游标

MySQL支持存储程序内部的游标。语法与嵌入式SQL中的语法相同。游标具有以下属性:

  • 不敏感:服务器可能会或可能不会复制其结果表

  • 只读:不可更新

  • 不可滚动:只能在一个方向上遍历,不能跳过行

游标声明必须出现在处理程序声明之前,变量和条件声明之后。

例:

CREATE PROCEDURE curdemo()
BEGIN
  DECLARE done INT DEFAULT FALSE;
  DECLARE a CHAR(16);
  DECLARE b, c INT;
  DECLARE cur1 CURSOR FOR SELECT id,data FROM test.t1;
  DECLARE cur2 CURSOR FOR SELECT i FROM test.t2;
  DECLARE CONTINUE HANDLER FOR NOT FOUND SET done = TRUE;

  OPEN cur1;
  OPEN cur2;

  read_loop: LOOP
    FETCH cur1 INTO a, b;
    FETCH cur2 INTO c;
    IF done THEN
      LEAVE read_loop;
    END IF;
    IF b < c THEN
      INSERT INTO test.t3 VALUES (a,b);
    ELSE
      INSERT INTO test.t3 VALUES (a,c);
    END IF;
  END LOOP;

  CLOSE cur1;
  CLOSE cur2;
END;
原文地址:https://www.cnblogs.com/wonchaofan/p/13521398.html