You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.24 13:36:04