提要:在本教程中,您将学习基于特定条件执行命令的PL/pgSQL 的 CASE语句。

除了IF语句之外,PostgreSQL 还为您提供 CASE 语句,允许您有条件地执行一段代码。CASE 语句有两种形式:简单的和搜索的 CASE 语句。

提示:请注意,您不应该混淆CASE语句和CASE表达式。CASE表达式评估为一个值,而CASE语句根据条件执行语句。

简单的 CASE 语句

让我们从简单的 CASE 语句开始:

CASE search-expression
   WHEN expression_1 [, expression_2, ...] THEN
      when-statements
  [ ... ]
  [ELSE
      else-statements ]
END CASE;

search-expression 是一个表达式,将在每个 WHEN 分支里使用相等(=)比较时进行计算。如果找到了匹配的项,则对应的 when-statements 会执行,而其它的判断子语句不会再执行。

ELSE 分支里的 else-statements 将在所有的 WHEN 分支都不匹配时执行。这个 ELSE 分支是可选的。如果没有指定 ELSE 分支,并且所有的 WHEN 都没有匹配成功,则会抛出 CASE_NOT_FOUND 异常。

下面是简单 CASE 的示例:

CREATE OR REPLACE FUNCTION get_price_segment(p_film_id integer)
   RETURNS VARCHAR(50) AS $$
DECLARE 
 rate   NUMERIC;
 price_segment VARCHAR(50);
BEGIN
   -- get the rate based on film_id
    SELECT INTO rate rental_rate 
    FROM film 
    WHERE film_id = p_film_id;

     CASE rate
 WHEN 0.99 THEN
            price_segment = 'Mass';
 WHEN 2.99 THEN
            price_segment = 'Mainstream';
 WHEN 4.99 THEN
            price_segment = 'High End';
 ELSE
     price_segment = 'Unspecified';
 END CASE;

   RETURN price_segment;
END; $$
LANGUAGE plpgsql;

在这个例子里,我们创建了一个名为 get_price_segment() 的函数,它接受 p_film_id 参数。根据电影出租率,它返回价格段:大众(Mass),主流(Mainstream),高端(High End)。 如果价格不是0.99,2.99或4.99,函数返回未指定(Unspecified)。

case

测试一下这个函数:

SELECT get_price_segment(123) AS "Price Segment";

case

搜索的 CASE 语句

语法如下:

CASE
    WHEN boolean-expression-1 THEN
      statements
  [ WHEN boolean-expression-2 THEN
      statements
    ... ]
  [ ELSE
      statements ]
END CASE;

搜索的 CASE 语句根据每个 WHEN 子句中布尔表达式的结果执行语句。PostgreSQL 按从上到下的顺序,依次判断 WHEN 表达式的结果,直到找到结果为 TRUEWHEN。如果没有找到结果为 TRUE 子句,则执行 ELSE 后的语句。这个 ELSE 分支是可选的。如果没有指定 ELSE 分支,并且所有的 WHEN 都没有匹配成功,则会抛出 CASE_NOT_FOUND 异常。

看个例子:

CREATE OR REPLACE FUNCTION get_customer_service (p_customer_id INTEGER) 
 RETURNS VARCHAR (25) AS $$ 
DECLARE
    total_payment NUMERIC ; 
    service_level VARCHAR (25) ;
BEGIN
 -- get the rate based on film_id
     SELECT
 INTO total_payment SUM (amount)
     FROM
 payment
     WHERE
 customer_id = p_customer_id ; 

   CASE
      WHEN total_payment > 200 THEN
         service_level = 'Platinum' ;
      WHEN total_payment > 100 THEN
 service_level = 'Gold' ;
      ELSE
         service_level = 'Silver' ;
   END CASE ;

   RETURN service_level ;
END ; $$ 
LANGUAGE plpgsql;

case

来看一下测试结果:

SELECT
 148 AS customer,
 get_customer_service (148)
UNION

SELECT
 178 AS customer,
 get_customer_service (178)
UNION

SELECT
 81 AS customer,
 get_customer_service (81);

case

上一篇:PL/pgSQL 的IF语句