如何创建校验其他表字段的PL/SQL行触发器并解决执行报错
错误原因
你遇到的ORA-01422报错和逻辑失效问题,来自触发器的两处核心错误:
- SELECT语句错误关联了已有的PRODUCT表,没有定位到当前待插入的新行对应的供应商,只要表中有多个符合
TRUSTED_SUPPLIER = 'YES'的记录,SELECT INTO就会返回多行,直接触发该报错。 - 逻辑完全写反:你在WHERE条件里提前过滤了可信供应商,后续即使查询成功拿到的也只会是
YES,根本走不到TRUST = 'NO'的判断分支;如果供应商不可信,这条SELECT会查不到数据,还会额外抛出ORA-01403未找到数据的错误。另外你写的RAISE_APPLICATION_ERROR错误码不符合Oracle规范,用户自定义错误码必须是-20000到-20999之间的负数。
修复后的触发器代码
CREATE OR REPLACE TRIGGER VERIFY_SUPPLIER_TRUST BEFORE INSERT ON PRODUCT FOR EACH ROW DECLARE v_trust VARCHAR(3); BEGIN -- 仅查询当前待插入产品对应的供应商的可信状态 SELECT TRUSTED_SUPPLIER INTO v_trust FROM SUPPLIER WHERE COMPANY_NAME = :NEW.SUPPLIER_NAME; -- 不可信(含字段为空的情况)就终止插入抛出错误 IF NVL(v_trust, 'NO') != 'YES' THEN RAISE_APPLICATION_ERROR(-20001, 'SUPPLIER NOT TRUSTED'); END IF; END; /
修复说明
- 去掉了多余的PRODUCT表关联,直接用
:NEW.SUPPLIER_NAME获取当前待插入行的供应商名称,由于SUPPLIER表的COMPANY_NAME是主键,查询结果永远只会返回1行,不会再出现返回多行的错误。 - 新增
NVL(v_trust, 'NO')处理TRUSTED_SUPPLIER为NULL的情况,默认空值视为不可信,避免空值判断异常。 - 修正了自定义错误码的格式,符合Oracle的语法要求。
内容的提问来源于stack exchange,提问作者user12062753
相关产品推荐
相关产品推荐

