繁体   English   中英

PL / SQL更新员工的工资,工资增加量是错误的

[英]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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM