MySQL CASE 语句
在本教程中,您将学习如何使用 MySQL CASE 语句在存储过程中构造复杂的条件语句。
摘要:在本教程中,您将学习如何使用 MySQL CASE 语句在存储过程中构造复杂的条件语句。
除了 IF 语句之外,MySQL 还提供了另一种条件语句,称为 CASE 在存储过程中构造条件语句的语句。这些 CASE 语句使代码更具可读性和效率。
该 CASE 声明有两种形式:简单 CASE 和搜索 CASE 语句。
请注意,如果要将 if-else 逻辑添加到 SQL 语句中,请使用与本教程中描述的语句不同的 CASE 表达式 CASE 。
简单的 CASE 语句
以下是简单 CASE 语句的基本语法:
CASE case_value
WHEN when_value1 THEN statements
WHEN when_value2 THEN statements
...
[ELSE else-statements]
END CASE;
在此语法中,简单 CASE 语句按顺序比较 case_value is 与 when_value1 , when_value2 , … 直到发现一个相等。当 CASE 发现 a case_value 等于 a 时 when_value ,它 statements 在相应的 THEN 子句中执行。
如果 CASE 无法找到任何 when_value 等于 case_value ,它执行 else-statements 的在 ELSE 条款如果 ELSE 条款是可用的。
当 ELSE 子句不存在并且 CASE 找不到任何 when_value 等于 时 case_value ,它会发出错误:
Case not found for CASE statement
请注意, case_value 可以是文字值或表达式。该 statements 可以是一个或多个SQL语句,而不能有零声明。
为了避免当 the case_value 不等于 any时的错误 when_value ,您可以 BEGIN END 在 ELSE 子句中使用一个空块,如下所示:
CASE case_value
WHEN when_value1 THEN ...
WHEN when_value2 THEN ...
ELSE
BEGIN
END;
END CASE;
简单 CASE 语句测试相等性 ( = ),您不能用它来测试相等性 NULL ;因为 NULL = NULL 返回 FALSE 。
简单 CASE 语句实例
以下存储过程说明了如何使用简单 CASE 语句:
DELIMITER $$
CREATE PROCEDURE GetCustomerShipping(
IN pCustomerNUmber INT,
OUT pShipping VARCHAR(50)
)
BEGIN
DECLARE customerCountry VARCHAR(100);
SELECT
country
INTO customerCountry FROM
customers
WHERE
customerNumber = pCustomerNUmber;
CASE customerCountry
WHEN 'USA' THEN
SET pShipping = '2-day Shipping';
WHEN 'Canada' THEN
SET pShipping = '3-day Shipping';
ELSE
SET pShipping = '5-day Shipping';
END CASE;
END$$
DELIMITER ;
这个怎么运作。
该 GetCustomerShipping() 存储过程接受两个参数: pCustomerNumber 作为 IN 参数,并 pShipping 作为一个 OUT 参数。
在存储过程中:
首先, customers 通过输入的客户编号从表中选择客户所在的国家/地区。
其次,使用简单的 CASE 语句根据客户所在的国家/地区确定发货时间。如果客户位于 USA ,发货时间为 2-day shipping 。如果客户位于 Canada ,发货时间为 3-day shipping 。来自其他国家的客户有 5-day shipping 。
下面的流程图演示了 CASE 语句确定发货时间的逻辑:
此语句调用存储过程并传递客户编号 112:
CALL GetCustomerShipping(112,@shipping);
以下语句返回客户 112 的运输时间:
SELECT @shipping;
这是输出:
+----------------+
| @shipping |
+----------------+
| 2-day Shipping |
+----------------+
1 row in set (0.00 sec)
搜索 CASE 语句
简单 CASE 语句只允许您将一个值与一组不同的值进行比较。
要执行更复杂的匹配(例如范围),请使用 searched CASE 语句。searched CASE 语句等同于 IF 语句,但是,它比 IF 语句更具可读性。
以下是搜索 CASE 语句的基本语法:
CASE
WHEN search_condition1 THEN statements
WHEN search_condition1 THEN statements
...
[ELSE else-statements]
END CASE;
在此语法中, searched CASE 对子句中的每个进行求值 search_condition , WHEN 直到找到求值为 的条件 TRUE ,然后执行相应的 THEN 子句 statements 。
如果 no search_condition 计算为 TRUE ,则如果子句可用, CASE 将 else-statements 在 ELSE 子句中执行 ELSE 。
与简单 CASE 语句类似,如果不指定 ELSE 子句且没有条件 is TRUE ,MySQL 会引发相同的错误:
Case not found for CASE statement
MySQL 也不允许您 statements 在 THEN or ELSE 子句中有空。如果您不想处理 ELSE 子句中的逻辑,同时防止 MySQL 在 no search_condition 为真时引发错误,您可以 BEGIN END 在 ELSE 子句中使用一个空块。
搜索 CASE 语句实例
下面的例子演示了如何使用搜索 CASE 语句找出客户的水平 SILVER , GOLD 或 PLATINUM 根据客户的信用额度。
DELIMITER $$
CREATE PROCEDURE GetDeliveryStatus(
IN pOrderNumber INT,
OUT pDeliveryStatus VARCHAR(100)
)
BEGIN
DECLARE waitingDay INT DEFAULT 0;
SELECT
DATEDIFF(requiredDate, shippedDate)
INTO waitingDay
FROM orders
WHERE orderNumber = pOrderNumber;
CASE
WHEN waitingDay = 0 THEN
SET pDeliveryStatus = 'On Time';
WHEN waitingDay >= 1 AND waitingDay < 5 THEN
SET pDeliveryStatus = 'Late';
WHEN waitingDay >= 5 THEN
SET pDeliveryStatus = 'Very Late';
ELSE
SET pDeliveryStatus = 'No Information';
END CASE;
END$$
DELIMITER ;
这个怎么运作。
存储过程 GetDeliveryStatus() 接受订单号作为 IN 参数,并返回交货状态作为 OUT 参数。
首先,计算所需日期和发货日期之间的天数。
其次,使用搜索到的 CASE 语句根据等待天数确定交货状态:
- 如果等待天数为零,则交货准时。
- 当等待天数在 1 到 5 之间时,交货会延迟。
- 当等待天数超过 5 天时,则交货很晚。
- 如果等待天数为 NULL 或其他,则交付处于
ELSE子句中未指定信息的状态。
此语句使用存储过程 GetDeliveryStatus() 获取订单的交货状态 10100 :
CALL GetDeliveryStatus(10100,@delivery);
结果如下:

MySQL CASE 对比 IF
无论 IF 和 CASE 语句,可以执行基于特定条件的代码块。在 IF 或 CASE 有时之间进行选择只是个人喜好的问题。以下是一些指导方针:
- 当您将单个表达式与一系列唯一值进行比较时,简单
CASE语句比语句更具可读性和效率IF。 - 当您检查基于多个值的复杂表达式时,该
IF语句更容易理解。 - 如果使用该
CASE语句,则必须确保至少满足其中一个CASE条件。否则,您需要定义一个错误处理程序来捕获错误。请注意,您不必对IF语句执行此操作。 - 在某些情况下,您可以同时使用
IF和CASE使代码更具可读性和效率。
在本教程中,您学习了如何使用两种形式的 MySQL CASE 语句,包括简单 CASE 语句和搜索 CASE 语句。
