如何在Oracle SQL中正确处理异常 完成员工薪资调整的错误处理需求
异常无法触发的核心原因
你触发不了预期异常的最常见原因是查询Peter薪资时使用了聚合函数(如MAX/AVG/COUNT),Oracle的NO_DATA_FOUND、TOO_MANY_ROWS两个预定义异常,仅会在SELECT ... INTO语句返回0行、或返回超过1行时触发,如果使用聚合函数,无论匹配多少条Peter的记录,都会返回1行聚合结果,自然不会抛出异常。
可直接运行的存储过程实现
CREATE OR REPLACE PROCEDURE update_emp_129_sal AS v_peter_sal NUMBER(10,2); v_avg_all_sal NUMBER(10,2); v_min_peter_sal NUMBER(10,2); BEGIN -- 不带聚合的单值查询,才会触发目标异常 SELECT salary INTO v_peter_sal FROM employees WHERE first_name = 'Peter'; -- 正常分支:只有1个Peter时执行更新 UPDATE employees SET salary = v_peter_sal WHERE employee_id = 129; COMMIT; DBMS_OUTPUT.PUT_LINE('129号员工薪资已更新为Peter的薪资:'||v_peter_sal); EXCEPTION -- 场景1:没有叫Peter的员工 WHEN NO_DATA_FOUND THEN SELECT AVG(salary) INTO v_avg_all_sal FROM employees; DBMS_OUTPUT.PUT_LINE('未找到Peter,所有员工平均薪资为:'||v_avg_all_sal); -- 场景2:有多个叫Peter的员工,你当前有3个Peter会触发这个分支 WHEN TOO_MANY_ROWS THEN SELECT MIN(salary) INTO v_min_peter_sal FROM employees WHERE first_name = 'Peter'; DBMS_OUTPUT.PUT_LINE('存在多个Peter,所有Peter的最低薪资为:'||v_min_peter_sal); -- 其他异常兜底 WHEN OTHERS THEN ROLLBACK; DBMS_OUTPUT.PUT_LINE('操作出错,错误码:'||SQLCODE||',错误信息:'||SQLERRM); END update_emp_129_sal; /
执行说明
- 运行存储过程前先执行命令开启输出:
SET SERVEROUTPUT ON;,否则看不到打印结果 - 请根据你实际的表结构调整字段名:若名字字段为
emp_name、表名为emp、薪资字段为sal,自行替换代码中对应的字段和表名 - 执行存储过程的命令:
EXEC update_emp_129_sal;
内容的提问来源于stack exchange,提问作者Szilvi789
相关产品推荐
相关产品推荐

