PL/SQL-Why工资不是涨了20%吗?

PL/SQL-Why is the salary not increased by 20%?

当我输入employee_id时,无论job_title还是Salary amount,工资都没有增加20%,变成6336$。是因为错误的 IF 语句吗?我怎么解决这个问题?另外,SELECT下方有一条黄色波浪线。这是什么意思?我正在使用 Oracle SQL 开发人员。

我的代码:

CREATE OR REPLACE PROCEDURE raise_emp_salaries (
p_emp_id IN NUMBER) AS

CURSOR c_emp IS
SELECT
    country_name,
    job_title,
    employees.employee_id,
    salary
FROM employees 
    JOIN departments on departments.department_id = employees.department_id
    JOIN locations on locations.location_id = departments.location_id
    JOIN countries ON countries.country_id = locations.country_id
    JOIN jobs ON jobs.job_id = employees.job_id;

rec_emp   c_emp%rowtype;
new_sal   NUMBER(9,2);
 
BEGIN 
OPEN c_emp; 
SAVEPOINT update_no;
LOOP
FETCH c_emp INTO rec_emp;
EXIT WHEN c_emp%notfound;

IF rec_emp.country_name = 'United States of America'
AND rec_emp.job_title IN ('Administration Assistant','Stock Manager') THEN
new_sal := rec_emp.salary * 1.20;
END IF;

   UPDATE employees
SET
    employees.salary = new_sal
WHERE
    employees.employee_id = p_emp_id;
COMMIT;  
end loop;
close c_emp;
end;`

您的 UPDATE 声明不在 IF 检查国家和职位的范围内;它用检测到的最后一个 new_sal 循环更新每个人的薪水。将它移到 IF..ENDIF.

不要使用游标,使用单个 UPDATE 语句:

CREATE PROCEDURE raise_emp_salaries(
  p_emp_id IN NUMBER
)
AS
BEGIN 
  UPDATE employees e
  SET   salary = salary * 1.2
  WHERE employee_id = p_emp_id
  AND   EXISTS(
          SELECT 1
          FROM   departments d
                 INNER JOIN locations l
                 ON l.location_id = d.location_id
                 INNER JOIN countries c
                 ON c.country_id = l.country_id
          WHERE  d.department_id = e.department_id
          AND    c.country_name = 'United States of America'
        )
  AND   EXISTS(
          SELECT 1
          FROM   jobs j
          WHERE  j.job_id = e.job_id
          AND    j.job_title IN ('Administration Assistant','Stock Manager')
        );
END;
/

注意:在过程中使用 COMMIT 意味着您不能在单个事务中将多个过程 and/or DML 语句链接在一起,然后对它们使用 ROLLBACK如果后面一个失败了。您应该删除 COMMIT 并在事务完成后在过程外部调用它。


Is it because of wrong IF Statement? How can I solve this problem?

您的程序有几个缺陷:

  1. 正如 userMT 在 中指出的那样,UPDATE 语句在 IF 语句之外,因此您将为游标中的每一行更新 p_emp_id 记录最近匹配的工资。
  2. 您没有过滤 SELECT 语句中的行,因此每个员工都会出现在游标中。

如果你想用光标来做(你不应该)那么你想要这样的东西:

CREATE OR REPLACE PROCEDURE raise_emp_salaries (
  p_emp_id IN NUMBER
)
AS
  CURSOR c_emp IS
  SELECT employees.employee_id,
         salary
  FROM   employees 
         JOIN departments on departments.department_id = employees.department_id
         JOIN locations on locations.location_id = departments.location_id
         JOIN countries ON countries.country_id = locations.country_id
         JOIN jobs ON jobs.job_id = employees.job_id
  WHERE  country_name = 'United States of America'
  AND    job_title IN ('Administration Assistant','Stock Manager')
  AND    employee_id = p_emp_id;

  rec_emp   c_emp%rowtype;
BEGIN 
  OPEN c_emp; 
  LOOP
    FETCH c_emp INTO rec_emp;
    EXIT WHEN c_emp%notfound;

    UPDATE employees
    SET   salary      = c_emp.salary * 1.2
    WHERE employee_id = c_emp.employee_id;
  END LOOP;
  CLOSE c_emp;
END;
/

(假设每位员工只能在一个部门工作,并且该部门位于一个地点和一个国家,并且员工只有一份工作。如果可以有多个,那么就有将重复更新。它还假设 p_emp_id 匹配一个员工;如果你可以匹配多个员工,那么游标解决方案仍然会有问题。)