PL/SQL- 使用过程和游标更新薪水

PL/SQL- Updating salary by using Procedure and Cursor

我必须创建一个可以提高员工工资的程序。首先,它要求用户输入 employee_id。如果他的国家是美利坚合众国,职位是 Administration Assistant 或 Stock Manager ,那么加薪 20%。否则回滚。

我在创建过程时遇到问题。我不知道下一步该怎么做。现在有一个错误: 25/5 PL/SQL:语句被忽略 25/112 PLS-00382:表达式类型错误 你能帮帮我吗?

这是我的代码:

CREATE OR REPLACE PROCEDURE raise_emp_salaries (
p_emp_id IN NUMBER) AS

CURSOR c_emp IS
SELECT
    countries.country_name,
    jobs.job_title,
    employees.employee_id,
    employees.salary
FROM
    countries,
    jobs,
    employees;

rec_emp   c_emp%rowtype;
new_sal   NUMBER(12, 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'  --25/5      PL/SQL: Statement ignored 25/112 PLS-00382: expression is of wrong type
AND rec_emp.job_title = 'Administration Assistant' 
OR '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;

 EXCEPTION
WHEN NO_DATA_FOUND THEN
     DBMS_OUTPUT.PUT_LINE('NO RECORDS');
     ROLLBACK TO update_no;
WHEN OTHERS THEN
     DBMS_OUTPUT.PUT_LINE('FOUND SOME KIND OF ERROR');
     ROLLBACK TO update_no;
 
close c_emp;
end;

您的 and/or 不正确。更改为:

IF rec_emp.country_name = 'United States of America'
AND rec_emp.job_title IN ('Administration Assistant','Stock Manager') THEN

IN 基本上是一个 OR 但更容易阅读。 但是你也有逻辑问题。您 SELECT 语句使用了三个表,countries,jobs, employees,并且它们之间没有任何 JOIN。这不可能是正确的,因为这将导致所有三个表中所有行的 CROSS PRODUCT,这可能不是您想要的。由于您没有显示三个表的 DLL,IDK 它们之间的关系,因此您需要弄清楚 JOINS。

此外,通常更好的做法是不要在过程中执行 commit/rollback,并让过程的调用者确定它。如果调用者在会话中执行额外的 DML 怎么办?现在您的程序也具有提交这些更改的 side-effect。您应该 return 过程中的错误 code/message 或创建您自己的异常并引发这些异常。

更多 - 接受 OTHERS 异常而不提供详细信息也是不好的做法。此外,您永远不会遇到 NO_DATA_FOUND 游标实现方式的异常。

已编辑代码。

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;`