[英]PL/SQL-updating salary of an employee, the amount of increase in salary was wrong
我需要更新部门40和70的员工工资。部门40的所有员工将增加10%,而部门70的员工将增加15%。
我有一名来自70级的员工,他的薪水是10000,所以他的薪水会增加15%。 我希望他的薪水能够达到11500,但却变成了13225.我无法理解为什么。 来自部门40的员工有正确的加薪,只有70部门的员工错误。
这是pl / sql块..
SET serveroutput ON
DECLARE
CURSOR cur_emp
IS
SELECT * FROM employees WHERE department_id = 40 OR department_id = 70;
rec_emp cur_emp%rowtype;
BEGIN
OPEN cur_emp;
LOOP
FETCH cur_emp INTO rec_emp;
IF rec_emp.department_id = 40 THEN
UPDATE employees
SET salary = salary + (salary * 0.1)
WHERE employee_id = rec_emp.employee_id;
elsif rec_emp.department_id = 70 THEN
UPDATE employees
SET salary = salary + (salary * 0.15)
WHERE employee_id = rec_emp.employee_id;
END IF;
EXIT
WHEN cur_emp%notfound;
END LOOP;
CLOSE cur_emp;
END;
/
任何人都可以帮我解决这个问题吗? 谢谢
无需存储过程:
update employees
set salary = case
when department_id = 40 then salary * 1.10
when department_id = 70 then salary * 1.15
else salary -- not strictly necessary. just to make sure.
end
where department_id in (40,70);
如果你坚持这样做,那么使用UPDATE ... WHERE CURRENT OF
在什么时候当前的更慢的方式(PL / SQL中的循环)可能比“无关”更新更快。
你的代码真正的问题是你离开循环“太晚了”。 即使光标在获取后没有返回任何内容,您仍然会进行更新。 您应该在IF子句和更新之前放置EXIT WHEN ...
DECLARE
CURSOR cur_emp
IS
SELECT * FROM employees WHERE department_id = 40 OR department_id = 70;
rec_emp cur_emp%rowtype;
BEGIN
OPEN cur_emp;
LOOP
FETCH cur_emp INTO rec_emp;
EXIT WHEN cur_emp%notfound; -- **** leave the loop right here, BEFORE doing the update *****
IF rec_emp.department_id = 40 THEN
UPDATE employees
SET salary = salary + (salary * 0.1)
WHERE employee_id = rec_emp.employee_id;
elsif rec_emp.department_id = 70 THEN
UPDATE employees
SET salary = salary + (salary * 0.15)
WHERE employee_id = rec_emp.employee_id;
END IF;
END LOOP;
CLOSE cur_emp;
END;
/
更有效的方法是使用可更新的游标:
DECLARE
CURSOR cur_emp
IS
SELECT department_id, salary
FROM employees
WHERE department_id in (40,70)
FOR UPDATE OF salary;
rec_emp cur_emp%rowtype;
new_sal number(12,2);
BEGIN
OPEN cur_emp;
LOOP
FETCH cur_emp INTO rec_emp;
EXIT WHEN cur_emp%NOTFOUND;
IF rec_emp.department_id = 40 THEN
new_sal := rec_emp.salary * 1.10;
elsif rec_emp.department_id = 70 THEN
new_sal := rec_emp.salary * 1.15;
END IF;
UPDATE employees
SET salary = new_sal
WHERE CURRENT OF cur_emp;
END LOOP;
CLOSE cur_emp;
END;
/
WHERE CURRENT OF
的使用实际上会更清楚地揭示错误,因为如果在更新后放置exit
,循环将失败并invalid rowid
。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.