我在 PL SQL 中的 CASE 语句有啥问题?

Posted

技术标签:

【中文标题】我在 PL SQL 中的 CASE 语句有啥问题?【英文标题】:What is wrong with my CASE statement on PLSQL?我在 PL SQL 中的 CASE 语句有什么问题? 【发布时间】:2016-12-27 14:54:15 【问题描述】:

我正在编写一个简单的 CASE 代码,以便在员工赚取更多部门的 AVG 工资时打印在屏幕上。但是我不明白为什么当我想检查 2 名员工的工资时,我在屏幕上只看到一个结果。我希望你能理解我的问题。谢谢。

SET SERVEROUTPUT ON

DECLARE
  v_emp121_sal   employees.salary%TYPE;
  v_emp121_lname employees.last_name%TYPE;

  v_emp139_sal   employees.salary%TYPE;
  v_emp139_lname employees.last_name%TYPE;

  v_avgsal       employees.salary%TYPE;
BEGIN
  SELECT salary, last_name
  INTO   v_emp121_sal, v_emp121_lname
  FROM   employees
  WHERE  employee_id = 121;
    DBMS_OUTPUT.PUT_LINE('EMPLOYEE 121 SALARY IS: ' || v_emp121_sal);

  SELECT salary, last_name
  INTO   v_emp139_sal, v_emp139_lname
  FROM   employees
  WHERE  employee_id = 139;
    DBMS_OUTPUT.PUT_LINE('EMPLOYEE 139 SALARY IS: ' || v_emp139_sal);

  SELECT AVG(salary)
  INTO   v_avgsal
  FROM   employees
  WHERE  department_id = 50;
    DBMS_OUTPUT.PUT_LINE('DEPARTMENT 50 AVG SALARY IS: ' ||
                          TRUNC(v_avgsal, 0));


  CASE
      WHEN 
          v_emp121_sal < v_avgsal THEN
          DBMS_OUTPUT.PUT_LINE('SALARY OF EMP ' || v_emp121_lname ||
                               ' IS LESS THAN DEPARTMENT AVG');
      WHEN
          v_emp121_sal > v_avgsal THEN
          DBMS_OUTPUT.PUT_LINE('SALARY OF EMP ' || v_emp121_lname ||
                               ' IS HIGHER THAN AVG DEPARTMENT');
      WHEN
          v_emp139_sal < v_avgsal THEN
          DBMS_OUTPUT.PUT_LINE('SALARY OF EMP ' || v_emp139_lname ||
                               ' IS LESS THAN DEPARTMENT AVG');
      WHEN
          v_emp139_sal > v_avgsal THEN
          DBMS_OUTPUT.PUT_LINE('SALARY OF EMP ' || v_emp139_lname ||
                               ' IS HIGHER THAN AVG DEPARTMENT');
  END CASE;

END;
/

理论上,我应该在屏幕上收到 “EMP FRIPP 的薪水高于平均部门” "EMP SEO 的薪水低于平均部门"

【问题讨论】:

工资号码(8, 2) rattlesnake..你可以在这里发布你的工作代码供其他人参考 【参考方案1】:

case 表达式返回一个值。如果您需要为两名员工提供单独的输出,请使用 2 个case 表达式,以便每个人都返回自己的值。

CASE
      WHEN 
          v_emp121_sal < v_avgsal THEN
          DBMS_OUTPUT.PUT_LINE('SALARY OF EMP ' || v_emp121_lname ||
                               ' IS LESS THAN DEPARTMENT AVG');
      WHEN
          v_emp121_sal > v_avgsal THEN
          DBMS_OUTPUT.PUT_LINE('SALARY OF EMP ' || v_emp121_lname ||
                              ' IS HIGHER THAN AVG DEPARTMENT');
END CASE;

CASE
      WHEN
          v_emp139_sal < v_avgsal THEN
          DBMS_OUTPUT.PUT_LINE('SALARY OF EMP ' || v_emp139_lname ||
                               ' IS LESS THAN DEPARTMENT AVG');

      WHEN
          v_emp139_sal > v_avgsal THEN
          DBMS_OUTPUT.PUT_LINE('SALARY OF EMP ' || v_emp139_lname ||
                               ' IS HIGHER THAN AVG DEPARTMENT');
END CASE;

您可能还想为= 添加一个条件,以便在&gt;&lt; 条件失败时避免null 输出。

【讨论】:

@Rattlesnake - 进一步阐明为什么原始代码不产生 OP 想要的输出:在第一个 when 条件为真之前评估 case 表达式。一旦 when 条件为真,则返回 then 值/采取操作,并退出整个 case 表达式 - 不再进行评估或分配。 我正在考虑它,我试图用 IF 语句做同样的事情,但我收到了相同的结果(一个员工条件)有没有办法在同一个 CASE 或 IF 中检查员工的工资句子?感谢您的回复。 @Rattlesnake - 这是可能的。 WHEN v_emp_121_sal &gt; avg THEN ,而不是在单独的 WHEN 分支中。 明白了。所以我应该写类似“WHEN v_emp121_sal AND v_emp131_sal @Rattlesnake - 我不确定我是否理解这个要求。您选择了两名员工,他们的薪水都可能高于整个部门的平均水平,那么您想要一条消息说两者都高于平均水平?那么是的,WHEN sal1 &gt; avg and sal2 &gt; avg then PRINT MESSAGE1 (about BOTH employees) WHEN sal1 &gt; avg and sal2 &lt; avg then PRINT MESSAGE2 等。当薪水完全等于平均水平时,你想打印什么?

以上是关于我在 PL SQL 中的 CASE 语句有啥问题?的主要内容,如果未能解决你的问题,请参考以下文章

从 PL/SQL 块中的 CASE 语句调用 Procs:面临的问题

PL/SQL 在 CASE 语句中返回一个列表

SQL 'select' 和 PL/SQL 'select' 语句有啥区别?

SQL里if语句和case语句有啥区别吗?哪个使用更高效?就是查询更优化?

在 PL SQL 中使用“执行”和目录执行查询语句有啥区别?

按子句顺序排列的 PL SQL CASE