流程控制语句
MySQL的支持IF,CASE,ITERATE,LEAVE,LOOPWHILEREPEATRETURN,和用于存储程序中流程控制结构。它还支持内部存储功能。
如以下各节中的语法规范所示,这些构造中的许多构造还包含其他语句。这样的构造可以是嵌套的。例如,一条IF语句可能包含一个WHILE循环,而该循环本身包含一条CASE语句。
MySQL不支持FOR循环。
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存储程序的语句实现了复杂的条件构造。
注意还有一个expr,与这里描述的语句不同。该语句不能有子句,并且以代替。
CASECASECASEELSE NULLEND CASEEND
对于第一种语法,case_value是一个表达式。将该值与when_value每个WHEN子句中的表达式进行比较,直到其中一个相等为止。when_value找到相等时,将执行相应的THEN子句statement_list。如果不when_value等于,则执行ELSE子句statement_list(如果存在)。
NULL由于NULL = NULL为false ,因此无法使用此语法测试是否相等。请参见“使用空值”。
对于第二种语法,将评估每个WHEN子句search_condition表达式,直到一个为真为止,然后执行其对应的THEN子句statement_list。如果不search_condition等于,则执行ELSE子句statement_list(如果存在)。
如果否when_value或search_condition与测试的值匹配,并且该CASE语句不包含任何ELSE子句,则导致CASE语句错误找不到Case。
每个都statement_list包含一个或多个SQL语句;statement_list不允许为空。
要处理任何WHEN子句都没有值匹配的情况,请使用ELSE包含一个空BEGIN ... END块的,如本示例所示。(本节中此处使用的缩进ELSE仅是为了清楚起见,在其他方面并不重要。)
DELIMITER |CREATE PROCEDURE p()BEGIN DECLARE v INTDEFAULT 1; CASE vWHEN 2THEN SELECT v;WHEN 3THEN SELECT 0;ELSE BEGIN END ;END CASE;END ; |
IF语句
IF search_conditionTHEN statement_list [ELSEIF search_conditionTHEN statement_list] ... [ELSE statement_list]END IF 
IF存储程序的语句实现了基本的条件构造。
注意还有一个函数,与此处描述的语句不同。该语句可以具有,和子句,并以终止。
IF()IFIFTHENELSEELSEIFEND IF
如果给定的结果search_condition为true,则执行相应的THENor ELSEIF子句statement_list。如果没有search_condition匹配项,则执行该ELSE子句statement_list。
每个都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 > mTHEN SET s = '>';ELSEIF n = mTHEN 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 = mTHEN SET s = 'equals';ELSE IF n > mTHEN 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 ;
在此示例中,IF仅当n不等于时才评估内部m。
ITERATE语句
ITERATE label
ITERATE只能出现LOOP,REPEAT和WHILE语句。ITERATE表示“再次开始循环。”
LEAVE声明
LEAVE label
该语句用于退出具有给定标签的流控制构造。如果标签用于最外层存储的程序块,则LEAVE退出程序。
LEAVE可以内使用BEGIN ... END或循环结构(LOOP,REPEAT,WHILE)。
LOOP声明
[begin_label:]LOOP statement_listEND LOOP [end_label]
LOOP实现了一个简单的循环结构,使语句列表可以重复执行,该语句列表由一个或多个语句组成,每个;语句均以分号()语句定界符终止。重复循环中的语句,直到循环终止。通常,这是通过LEAVE声明来完成的。在已存储的函数内,RETURN也可以使用它完全退出该函数。
忽略包含循环终止语句会导致无限循环。
LOOP可以标记一个声明。有关标签使用的规则,请参见“SIGNAL语句”。
例:
CREATE PROCEDURE doiterate(p1 INT)BEGIN label1:LOOP SET p1 = p1 + 1;IF p1 < 10THEN ITERATE label1;END IF ;LEAVE label1;END LOOP label1;SET @x = p1;END ;
REPEAT语句
[begin_label:]REPEAT statement_listUNTIL search_conditionEND REPEAT [end_label]
REPEAT重复语句中的语句列表,直到search_condition表达式为真为止。因此,a REPEAT总是至少进入一次循环。statement_list由一个或多个语句组成,每个语句以分号(;)语句定界符终止。
REPEAT可以标记一个声明。有关标签使用的规则,请参见“SIGNAL语句”。
例:
mysql>delimiter // mysql>CREATE PROCEDURE dorepeat(p1 INT)BEGIN SET @x = 0;REPEAT SET @x = @x + 1;UNTIL @x > p1END 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_conditionDO statement_listEND WHILE [end_label]
WHILE只要search_condition表达式为真,就会重复语句中的语句列表。statement_list由一个或多个SQL语句组成,每个语句以分号(;)语句定界符终止。
WHILE可以标记一个声明。有关标签使用的规则,请参见“SIGNAL语句”。
例:
CREATE PROCEDURE dowhile()BEGIN DECLARE v1 INTDEFAULT 5;WHILE v1 > 0DO ...SET v1 = v1 - 1;END WHILE ;END ;
