MySQL 的 CASE 语句是一种条件表达式,用于根据不同的条件返回不同的结果,它类似于其他编程语言中的 switch 语句。任何 CASE 语句能做的事都可以用 IF 语句完成,但是 CASE 语句通常更可读并且在处理多个测试条件时更有效。
CASE 语句有两种形式。第一种形式通常被称为简单 CASE 语句,用来作为多个表达式的输出相比对,语法如下:
CASE expression WHEN value THEN statements [WHEN value THEN statements ...] [ELSE statements] END CASE;
其中,expression 为表达式,value 用来指定 expression 的期望值,如果 expression 的结果和期望的 value 一致,则执行该 WHEN THEN 下面的语句 statements。
我们可以使用简单 CASE 语句来检查客户忠诚度状态,如下:
CASE customer_status WHEN 'PLATINUM' THEN -- 优惠 20% WHEN 'GOLD' THEN -- 优惠 15% WHEN 'SILVER' THEN -- 优惠 10% WHEN 'BRONZE' THEN -- 优惠 5% END CASE;
就像 IF 命令一样,你可以指定多个 WHEN 语句并且你可以指定一个 ELSE 子句来执行其他条件未得到满足时的情况。
注意:CASE 语句将会在没有任何条件匹配的情况下产生异常。上例中,如果 customer_status 不是 “PLATINUM”、“GOLD”、“SILVER” 或 “BRONZE” 其中的任何一个,那么就会发生运行时异常:
ERROR 1339 (20000): Case not found for CASE statement
为了避免在未匹配到任何 CASE 语句时不产生错误,你可以为其创建一个错误处理单元来忽略错误,或者在 CASE 语句中使用 ELSE 子句确保异常永远不再发生。
查询 CASE 语句和 IF-ELSEIF-ELSE-END 块所具备的功能基本等同,查询 CASE 语句的语法:
CASE WHEN condition THEN statements [WHEN condition THEN statements...] [ELSE statements] END CASE;
从上面语法可知,并没有在 CASE 和 WHEN 之间放 condition 表达式,则是将表达式放在 WHEN 和 THEN 之间,这样一来,每个 WHEN 和 THEN 之间都可以放置表达式,甚至是不同的表达式。例如:
CASE WHEN (sale_value > 200 AND customer_status='PLATINUM') THEN -- 语句1 -- 语句2 WHEN (sale_value > 200 AND customer_status='GOLD') THEN -- 语句1 -- 语句3 WHEN (sale_value > 200 AND customer_status='SILVER') THEN -- 语句1 -- 语句4 WHEN (sale_value > 200 AND customer_status='BRONZE') THEN -- 语句1 -- 语句5 WHEN (sale_value > 200) THEN -- 语句1 END CASE;
请始终记住,CASE 没有匹配到任何 WHEN 语句,并且也没有设置 ELSE 语句,则产生一个 “ERROR 1339 (20000)” 错误。上面示例中,当 sale_value <= 200 时,将产生一个致命的错误,因此我们必须插入 ELSE 子句来保护我们的代码和工作的安全,例如:
CASE WHEN (sale_value > 200 AND customer_status='PLATINUM') THEN -- 语句1 -- 语句2 WHEN (sale_value > 200 AND customer_status='GOLD') THEN -- 语句1 -- 语句3 WHEN (sale_value > 200 AND customer_status='SILVER') THEN -- 语句1 -- 语句4 WHEN (sale_value > 200 AND customer_status='BRONZE') THEN -- 语句1 -- 语句5 WHEN (sale_value > 200) THEN -- 语句1 ELSE -- 哑语句 select 1; END CASE;
注意,因为 MySQL 在存储程序语言中缺乏 NULL 语句(不干任何事的),所以我们必须加入一个哑语句,但是这个语句开销几乎为 0。
除了添加 ELSE 语句,我们还可以使用嵌套 CASE 语句来写一个逻辑更为清晰的版本。该版本结合了简单 CASE 和查询 CASE 语句,并且包含了一个 “not found” 的错误处理单元来避免使用 ELSE 语句。如下:
BEGIN -- 错误处理,后续章节介绍 DECLARE not_found INT DEFAULT 0; DECLARE CONTINUE HANDLER FOR 1339 SET not_found=1; -- 一个查询 CASE CASE WHEN (sale_value>200) THEN -- 语句1 -- 一个嵌套的简单 CASE CASE customer_status WHEN 'PLATINUM' THEN -- 语句2 WHEN 'GOLD' THEN -- 语句3 WHEN 'SILVER' THEN -- 语句4 WHEN 'BRONZE' THEN -- 语句5 END CASE; END CASE; END;
在 MySQL 中,“哑语句” 是指在存储过程或函数中使用的一个空语句或无操作语句。它通常用于占位或标记某个逻辑操作的位置,但实际上不执行任何有意义的操作。
哑语句可以是一个空的 SELECT 语句、一个空的 UPDATE 语句、一个空的 INSERT 语句。它们的目的是为了保持代码结构的完整性和一致性,或者为将来的开发或维护留下一些提示。
下面是一些常见的哑语句示例:
空的 SELECT 语句:
-- 实际的查询操作,只是返回一个固定的结果 SELECT 1; 空的 UPDATE 语句: -- 没有实际的更新操作,只是将每一行的column1列的值设置为它自己 UPDATE my_table SET column1 = column1;
空的 INSERT 语句:
-- 没有实际的插入操作,只是插入一个空的行 INSERT INTO my_table VALUES ();
哑语句在编写存储过程或函数时很常见,它们可以用于占位或标记代码中的某个位置,以便日后的开发人员可以在这里添加实际的逻辑操作。此外,它们还可以提高代码的可读性和可维护性。