if语句必须在begin...end块中使用,不能单独执行;mysql的if是过程式控制语句,仅限存储过程、函数或触发器内;直接在查询窗口写if会报错error 1064;需用delimiter $$临时修改分隔符;布尔表达式中null须用is null判断;各分支及end if后均需加分号;嵌套if须逐层配对end if;case分表达式型(用于select/set)和语句型(用于begin...end内,支持多语句),二者不可混用;浮点比较应使用abs(a-b)

IF语句必须写在BEGIN...END块里,不能单独执行
MySQL的IF是过程式控制语句,不是函数,只能出现在存储过程、函数或触发器体内。直接在查询窗口里写IF score > 90 THEN SELECT 'A'; END IF;会报错ERROR 1064 (42000)。
- 必须用
DELIMITER $$临时改分隔符,否则;会让MySQL提前结束定义 -
IF后接布尔表达式,NULL不能用=判断,得写col IS NULL - 每个分支结尾、
END IF后面都必须加分号,漏掉一个就编译失败 - 嵌套
IF时,每层都要配对END IF;,常见错误是只写了一个END IF;却有两层IF
CASE语句分“表达式型”和“语句型”,别混用
你在SELECT里用的CASE WHEN ... THEN ... END是表达式,返回值;而存储过程里的CASE ... WHEN ... THEN ... END CASE;是语句,能执行多条SQL、调用INSERT或SET等操作——两者语法结构不同,互不兼容。
- 表达式型
CASE可以嵌在SELECT、SET中,比如SET @level = CASE WHEN score >= 90 THEN 'A' ELSE 'B' END; - 语句型
CASE必须写在BEGIN...END内,且WHEN后只能跟条件(不是值),例如WHEN age > 65 THEN INSERT INTO senior VALUES(...); - 没写
ELSE又没匹配到任何WHEN,会触发ERROR 1339 (42000): Case not found for CASE statement - 简单
CASE col WHEN val THEN ...只支持等值判断,范围或复杂逻辑得用搜索型CASE WHEN condition THEN ...
浮点比较、空值处理、类型隐式转换容易出错
数值精度和NULL是高频翻车点。比如IF price = 99.9 THEN ...可能永远不进分支,因为浮点存储误差导致实际值是99.89999999999999;IF status = NULL也永远为假,因为NULL = NULL返回NULL而非TRUE。
- 浮点字段比较务必用
ABS(a - b) 代替<code>a = b -
NULL判断必须显式写col IS NULL或col IS NOT NULL - 表达式型
CASE所有分支返回类型要一致,混合INT和VARCHAR会导致隐式转成字符串,可能意外截断或补空格 -
IF()函数和IF语句名字一样但完全无关:前者只能返回一个值,后者才能控制流程
参数传递影响判断逻辑的封装性
带IN参数的存储过程能把判断逻辑复用起来,但要注意OUT变量必须在调用前用@var声明,且CALL后要用SELECT @var取值;INOUT则适合需要“传入+修改+返回”的场景,比如把200分制成绩折算成百分制。
-
IN参数不可被修改,想改得先DECLARE局部变量再SET -
OUT参数在存储过程内必须赋值,否则调用后值为NULL - 多个
ELSEIF分支顺序很重要:MySQL从上到下匹配,第一个为TRUE的就执行,后面的不管——所以范围判断要从大到小写,比如score >= 90放最前,score >= 60放中间
真正麻烦的是嵌套深度和可读性平衡:三层以上IF缩进难维护,这时哪怕性能没差别,也该换用CASE语句;而CASE里如果每个THEN后面要执行一堆语句,记得用分号分隔,别漏掉任一分号。











