Основная проблема заключается в том, что вы неправильно поместили конец блока CASE
и предложение where после 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;
/