首页 > 解决方案 > 查看 PL SQL 中的 IF、WHERE 和 WHEN

问题描述

我正在完成一项学术作业,要求提示用户输入他们的目标销售额和员工 ID。如果目标销售额超过或等于2015年公司实际销售额,则可以申请加薪。

我已经编写了大部分代码,但我被困在 END IF 上;第 25 行的声明。我收到错误

ORA-06550、PLS-00103:在预期以下情况之一时遇到符号“WHERE”。

我想我可能很难整合将用户输入与 2015 年公司销售额进行比较的 if 语句。

非常感谢您的见解!谢谢!

accept emp_target prompt 'Please enter your company sales target: '
accept empno prompt 'Please enter your employee ID: '
DECLARE
emp_target NUMBER := &emp_target; 
cmp_target NUMBER;
empno   emp_employees.emp_id%type := &empno;
new_sal emp_employees.salary%type;
cnt     number; 

CURSOR sales_cur IS 
    SELECT SUM(oe_orderDetails.quoted_price)
    FROM oe_orderDetails
    JOIN oe_orderHeaders
    ON oe_orderDetails.order_id = oe_orderHeaders.order_id
    WHERE oe_orderHeaders.order_date >= to_date('1.1.' || 2015, 'DD.MM.YYYY')
    and oe_orderHeaders.order_date < to_date('1.1.' || (2015 + 1), 'DD.MM.YYYY');

BEGIN
OPEN sales_cur;
FETCH sales_cur INTO cmp_target;
IF cmp_target >= emp_target THEN 
    UPDATE emp_employees SET
        emp_employees.salary = case WHEN emp_employees.dept_id = 10 THEN emp_employees.salary * 1.1
        WHEN emp_employees.emp_id = 145 THEN emp_employees.salary * 1.15
        WHEN emp_employees.dept_id = 80 THEN emp_employees.salary * 1.2
        ELSE emp_employees.salary
    END IF;

END

WHERE emp_employees.emp_id = empno
returning emp_employees.salary into new_sal;

cnt := sql%rowcount;

IF cnt > 0 THEN
    dbms_output.put_line('Employee ' || empno || ', new salary = ' || new_sal);
ELSE
dbms_output.put_line('Nobody got new salary');
END IF;
END;

/

标签: sqloracleplsqlora-06550

解决方案


主要问题是您将CASE块的 end 和 where 子句放错了 after END IF

除此之外,我会说光标块不需要存储简单的SUM,但我会让你使用它,因为你正在学习作业。

修复第一个问题后的另一个问题是您的returning emp_employees.salary into new_sal. 标量变量不能包含从更新多行的 dml 返回的行。您应该改用集合(嵌套表)。用于RETURNING BULK COLLECT INTO加载它并稍后循环显示您的最终消息。

请仔细阅读我所有的代码注释。我无法测试整个代码是否有任何错误,因为我没有您的表格。如果可以的话,您应该修复,如果不能,请告诉我们。

ACCEPT emp_target PROMPT 'Please enter your company sales target: '
ACCEPT empno PROMPT 'Please enter your employee ID: '
DECLARE
     emp_target   NUMBER := &emp_target;
     cmp_target   NUMBER;
     empno        emp_employees.emp_id%TYPE := &empno;
     TYPE sal_type IS
          TABLE OF emp_employees.salary%TYPE; --nested table(collection) of salary
     new_sal      sal_type; -- a collection variable
     cnt          NUMBER;
     CURSOR sales_cur IS SELECT SUM(oe_orderdetails.quoted_price)
                         FROM oe_orderdetails
                         JOIN oe_orderheaders ON oe_orderdetails.order_id = oe_orderheaders.order_id
                         WHERE oe_orderheaders.order_date >= TO_DATE('1.1.' || 2015,'DD.MM.YYYY') AND
                         oe_orderheaders.order_date < TO_DATE('1.1.' || (2015 + 1),'DD.MM.YYYY'); --is it required to specify (2015 + 1) instead of 2016?
BEGIN
     OPEN sales_cur;

     FETCH sales_cur INTO cmp_target;

     IF
          cmp_target >= emp_target
     THEN
          UPDATE emp_employees
          SET
               emp_employees.salary =
                    CASE
                         WHEN emp_employees.dept_id = 10 THEN emp_employees.salary * 1.1
                         WHEN emp_employees.emp_id = 145 THEN emp_employees.salary * 1.15
                         WHEN emp_employees.dept_id = 80 THEN emp_employees.salary * 1.2
                         ELSE emp_employees.salary
                    END
          WHERE emp_employees.emp_id = empno --misplaced where and end
           RETURNING emp_employees.salary BULK COLLECT INTO new_sal;
     END IF;

     cnt := new_sal.count; --no of records in nested table

     IF
          cnt > 0
     THEN
          FOR i IN new_sal.first..new_sal.last LOOP
               dbms_output.put_line('Employee ' || empno || ', new salary = ' || new_sal(i) );
          END LOOP;
     ELSE
          dbms_output.put_line('Nobody got new salary');
     END IF;
     CLOSE sales_cur; -- always remember to close the cursor
END;

/

推荐阅读