Я вижу много потенциальных ошибок, некоторые из которых связаны с вашей проблемой, а некоторые нет.
Во-первых, настоящая причина вашей ошибки заключается в том, что ваш курсор не фильтрует идентификатор сотрудника. Таким образом, вы накапливаете для всех сотрудников.
Далее, вам не следует выполнять SELECT ... FOR UPDATE в функции. Цель функции - вернуть значение. Период. Полная остановка. Не следует ожидать обновления.
Далее вы продолжаете сравнивать Годовой заработок с некоторым фиксированным значением, но я не вижу нигде в коде, где вы присваиваете значение Годовому окладу.
Помимо этих технических ошибок Если бы я писал это, я бы сделал несколько «стилевых» изменений.
Во-первых, нет смысла писать код в смешанном регистре в oracle. Хотя с технической точки зрения в этом нет ничего плохого, это все равно что говорить по-английски sh (oracle) с сильным французским (Microsoft) акцентом. В мире oracle вместо смешанного регистра («CamelCase») мы склонны использовать все строчные буквы с подчеркиванием. Например, вместо «EmployeeName» мы будем использовать «employee_name».
Далее, в вашем объявлении переменной, я настоятельно рекомендую стандартизировать некоторые префиксы для указания типа переменной: «p_» для parms, «v_» для переменных, «c_» для констант. Таким образом, когда вы увидите там ссылки в длинном коде, станет ясно, что это за элемент. Чтобы изменить ваш код в соответствии с этим стандартом:
create or replace function bonuss
(p_emp_id in number)
return number
as
v_sal employees.salary%type;
v_commis employees.commission_pct%type;
v_annual_salary number;
v_bonus number;
Далее, если бы я использовал явный курсор (я бы не стал), я бы дал ему осмысленное имя, которое также указывает (для дальнейшего использования) что это курсор:
cursor csr_emp IS
Но я бы вообще не использовал явный курсор. Я бы использовал 'курсор для l oop':
begin
for x in (select salary,
commission_pct
from employees
where emp_id = p_emid '<<---- important to your case!)
)
if x.commission_pct is null
<rest of code>
loop;
end;
Но так как кажется, что вы хотите, чтобы функция возвращала бонус для одного сотрудника (иначе, почему emp_id является входным параметром ?) вам даже не нужен курсор вообще.