leave必须带显式声明的标签,否则报error 1064;标签需前置定义(如outer_loop: loop)、区分大小写、不与变量等重名;仅跳出当前作用域内可见标签,不可穿透嵌套;须手动清理游标、事务及handler。

LEAVE必须带显式标签,否则直接报错
MySQL不接受裸写的LEAVE,也不接受拼写错误或未声明的标签名。常见错误是写成LEAVE;或LEAVE my_loop;但没在前面用my_loop: LOOP或my_loop: BEGIN定义它。
标签名区分大小写,且不能和变量、游标、存储过程名重名,否则触发ERROR 1305 (42000): PROCEDURE does not exist。
- 正确写法:先声明
outer_loop: LOOP,再在内部用LEAVE outer_loop; - 错误写法:
LEAVE outer_loop;出现在outer_loop作用域之外(比如嵌套太深) - 调试技巧:把标签统一放在存储过程开头的
BEGIN前,确保所有循环都能引用
ITERATE只能用于循环体内部,不能跳出BEGIN块
ITERATE语义上等价于continue,只对LOOP、WHILE、REPEAT有效。它不会跳过整个程序体,也不能用在IF或BEGIN...END块里——那样会报ERROR 1305或ERROR 1064。
- 可用场景:在
WHILE循环中跳过当前轮次,比如过滤掉NULL值后直接ITERATE loop_label; - 不可用场景:写在
IF ... THEN ITERATE main_block;里——main_block如果是BEGIN标签,ITERATE不认 - 替代方案:想“跳过一段逻辑”,改用
IF条件包裹,而不是强行用ITERATE
嵌套循环中LEAVE无法穿透层级,必须靠标签作用域设计
MySQL的LEAVE只认**最近一层可见的同名标签**。如果在inner_loop里写LEAVE outer_loop,而outer_loop只在中间一层BEGIN里声明,内层就看不到它。
- 安全做法:把外层标签(如
proc_main:或outer_loop:)定义在存储过程最外层BEGIN之前 - 风险操作:依赖“标签就近查找”误判作用域,导致跳到错误位置甚至静默失败
- 更稳方案:用布尔标志变量(如
should_exit BOOLEAN DEFAULT FALSE)配合多层IF判断,避免跨层跳转
LEAVE跳出时容易遗漏资源清理,尤其游标和事务
LEAVE只是控制流跳转,不触发自动回滚、不关闭游标、不释放锁。如果在循环中打开游标cur_data,又在中间用LEAVE跳出,cur_data就一直开着,下次调用可能报Cursor is already open。
- 必须手动
CLOSE cur_data;再LEAVE,顺序不能反 - 事务中提前
LEAVE,需在跳转前加ROLLBACK;或确保已COMMIT; - Handler(如
DECLARE CONTINUE HANDLER FOR NOT FOUND)的作用域只覆盖其所在BEGIN...END块,跨块LEAVE后handler失效,可能让异常漏处理
LEAVE能替你收尾——它只管跳,不管擦屁股。











