Глядя на IF, WHERE и WHEN в PL SQL - PullRequest
       23

Глядя на IF, WHERE и WHEN в PL SQL

0 голосов
/ 08 октября 2018

Я выполняю академическое задание, в котором просит пользователя указать свои целевые продажи и идентификатор сотрудника.Если целевые продажи превышают или равны фактическим продажам компании за 2015 год, то могут применяться повышения.

Я написал большую часть кода, но застрял в END IF;операторы в строке 25. Я получаю сообщение об ошибке

ORA-06550, PLS-00103: обнаружен символ "ГДЕ" при ожидании одного из следующих действий.

Я думаю, что, возможно, изо всех сил пытаюсь интегрировать утверждение if, которое сравнивает входные данные пользователя с продажами компании за 2015 год.

Высоко ценится понимание!Спасибо!

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;

/

1 Ответ

0 голосов
/ 08 октября 2018

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

/
...