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 语句确定发货时间的逻辑:

MySQL CASE 语句流程图
MySQL 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 语句。