PL/SQL calculate_salary存储过程薪资计算错误排查求助
错误汇总
- 入参与字段重名、WHERE条件匹配错误:存储过程入参名和EMPLOYEES表的EMPLOYEE_ID字段重名,Oracle解析时会优先识别为字段名,导致
WHERE EMPLOYEE_ID = EMP_ID逻辑失效,且EMP_ID是未赋值的局部变量,永远无法匹配到数据。 - 变量类型定义错误:LAST_NAME变量错误引用了FIRST_NAME的类型,应该对应EMPLOYEES表的LAST_NAME字段类型。
- 在职年限计算不符合规则:用ROUND计算年限会把不满1年的情况四舍五入,不符合「满1年才涨薪」的要求,应该用FLOOR向下取整,只计算完整在职年数。
- 薪资计算逻辑完全错误:循环中直接用基础薪资乘循环次数,没有实现逐年5%复利上涨的逻辑,正确逻辑应该是初始薪资等于基础薪资,每满1年在上一年薪资基础上乘1.05。
- 循环范围错误:循环范围设为
0..TENURE会多执行一次涨薪计算,比如满2年的员工会循环3次,最终薪资多涨一次5%。
修正后的完整代码
CREATE OR REPLACE PROCEDURE calculate_salary(P_EMPLOYEE_ID EMPLOYEES.EMPLOYEE_ID%TYPE) AS increase FLOAT := 1.05; base_salary NUMBER := 10000; TENURE NUMBER; SALARY NUMBER; FIRST_NAME EMPLOYEES.FIRST_NAME%TYPE; LAST_NAME EMPLOYEES.LAST_NAME%TYPE; BEGIN -- 查询员工信息和完整在职年限 SELECT FIRST_NAME, LAST_NAME, FLOOR((SYSDATE - HIRE_DATE)/365) INTO FIRST_NAME, LAST_NAME, TENURE FROM EMPLOYEES WHERE EMPLOYEE_ID = P_EMPLOYEE_ID; -- 初始薪资为基础薪资 SALARY := base_salary; -- 每满1年涨一次薪 FOR i IN 1..TENURE LOOP SALARY := SALARY * increase; END LOOP; -- 按要求输出结果 DBMS_OUTPUT.PUT_LINE ('First Name: '||FIRST_NAME); DBMS_OUTPUT.PUT_LINE ('Last Name: '||LAST_NAME); DBMS_OUTPUT.PUT_LINE ('Salary: '||TO_CHAR(SALARY,'$99,999.99')); EXCEPTION WHEN NO_DATA_FOUND THEN DBMS_OUTPUT.PUT_LINE ('No Data Found!'); WHEN OTHERS THEN DBMS_OUTPUT.PUT_LINE ('Error!'); END; / -- 调用示例 BEGIN calculate_salary(1); END; /
内容的提问来源于stack exchange,提问作者tomtom
相关产品推荐
相关产品推荐

