You need to enable JavaScript to run this app. 如何通过SQL触发器跨表比较值?编写价格校验触发器遇PL/SQL报错
优惠活动
大模型
产品
解决方案
定价
更多

如何通过SQL触发器跨表比较值?编写价格校验触发器遇PL/SQL报错

原报错中文翻译
  • 错误(2,3):PL/SQL:SQL 语句被忽略
  • 错误(2,69):PL/SQL:ORA-00904 错误:LIEN_FABRICANT_PRODUIT 表的 PRIXFABRICANT 为无效标识符
  • 错误(2,92):PLS-00302 错误:必须声明组件 PRIXFABRICANT
  • 错误(5,3):PL/SQL:语句被忽略
  • 错误(5,10):PLS-00201 错误:必须声明标识符 NEW.PRIXVENTE
错误原因拆解
  • ORA-00904 无效标识符:优先检查LIEN_FABRICANT_PRODUIT表的出厂价字段实际命名,可执行DESC LIEN_FABRICANT_PRODUIT查看字段列表,常见错误包括拼写偏差、漏写下划线、建表时使用大小写敏感引号导致字段名实际为小写等。
  • PLS-00302 未声明PRIXFABRICANT:你编写的关联查询没有将结果赋值给PL/SQL变量,直接在IF判断中引用该字段,编译器无法识别变量来源。
  • PLS-00201 未声明NEW.PRIXVENTE:行级触发器的内置绑定变量NEW、OLD在PL/SQL块中引用时必须加冒号前缀,不加冒号会被编译器识别为未声明的普通标识符;同时前面的SQL语句语法错误导致编译器上下文异常,也会触发该报错。
  • 逻辑漏洞:原SELECT语句全表关联ARTICLE和出厂价关联表,没有用当前正在更新的商品行的产品、厂商ID做匹配,就算查询到值也不是当前行对应的出厂价。
修正后的触发器代码

请先确认LIEN_FABRICANT_PRODUIT的实际出厂价字段名,替换下方代码中对应字段后执行:

CREATE OR REPLACE TRIGGER Comparer_Prix 
BEFORE UPDATE ON ARTICLE 
FOR EACH ROW 
DECLARE
  -- 锚定表字段类型定义变量,避免类型不匹配问题
  v_prix_fab LIEN_FABRICANT_PRODUIT.PRIXFABRICANT%TYPE;
BEGIN
  -- 用当前更新行的产品、厂商ID匹配对应的出厂价,赋值给变量
  SELECT PRIXFABRICANT 
  INTO v_prix_fab
  FROM LIEN_FABRICANT_PRODUIT 
  WHERE 
    N_PRODUIT = :NEW.N_PRODUIT 
    AND N_FABRICANT = :NEW.N_FABRICANT;
  
  -- 执行业务规则校验
  IF :NEW.PRIXVENTE < v_prix_fab THEN 
    RAISE_APPLICATION_ERROR(-20001, 'Refusé : 销售价格不能低于出厂价格'); 
  END IF; 

EXCEPTION
  -- 处理无匹配出厂价记录的情况,避免触发隐式错误
  WHEN NO_DATA_FOUND THEN
    RAISE_APPLICATION_ERROR(-20002, 'Refusé : 未找到对应产品的出厂价记录');
END;
补充说明
  • 如果新增商品(INSERT操作)时也需要校验该规则,可将触发条件修改为BEFORE INSERT OR UPDATE ON ARTICLE,同时支持两种操作的校验。
  • 如果N_PRODUIT + N_FABRICANT不是LIEN_FABRICANT_PRODUIT表的唯一主键,可能存在多条匹配的情况,需要先补充该联合字段的唯一性约束,否则SELECT INTO会报单行子查询返回多行的错误。

内容的提问来源于stack exchange,提问作者Thomas Aspa

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.11.09 00:54:09