流程控制语句
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 (LOOP
, REPEAT
, WHILE
).
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;
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 记一次.NET内存居高不下排查解决与启示
· 探究高空视频全景AR技术的实现原理
· 理解Rust引用及其生命周期标识(上)
· 浏览器原生「磁吸」效果!Anchor Positioning 锚点定位神器解析
· 没有源码,如何修改代码逻辑?
· 分享4款.NET开源、免费、实用的商城系统
· 全程不用写代码,我用AI程序员写了一个飞机大战
· MongoDB 8.0这个新功能碉堡了,比商业数据库还牛
· 记一次.NET内存居高不下排查解决与启示
· 白话解读 Dapr 1.15:你的「微服务管家」又秀新绝活了