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

创建多个PL/SQL触发器时遇编译错误,请求问题排查

解决PL/SQL触发器编译错误问题

错误原因分析

你遇到的编译错误主要源于两个核心问题:

  • 未正确引用行级触发器的新/旧值:所有触发器中直接写phone_id,PL/SQL无法识别这是当前触发行的字段值,会被当成普通列名处理,导致ORA-00984: column not allowed here错误。
  • INSERT触发器中误用:old值:第三个触发器是AFTER INSERT类型,插入操作不存在旧行数据,所以:old.quantity是无效的——插入前根本没有这条记录的旧值。

修正后的触发器代码

下面是修复后的完整触发器创建语句,每个触发器都正确处理了行值引用和INSERT场景的限制:

-- SellingPrice变更日志触发器
CREATE OR REPLACE TRIGGER trigger_selling_price_change
AFTER INSERT OR UPDATE ON SellingPrice
FOR EACH ROW
BEGIN
    dbms_output.put_line('price of phone updated');
    INSERT INTO LogSellingPriceChange 
    VALUES(sysdate, :new.phone_id, :old.price, :new.price);
END;
/

-- PurchaseCost变更日志触发器
CREATE OR REPLACE TRIGGER trigger_purchase_cost_change
AFTER INSERT OR UPDATE ON PurchaseCost
FOR EACH ROW
BEGIN
    dbms_output.put_line('purchase cost updated');
    INSERT INTO LogPurchaseCostChange 
    VALUES(sysdate, :new.phone_id, :old.cost, :new.cost);
END;
/

-- Inventory新增日志触发器(适配INSERT无旧值场景)
CREATE OR REPLACE TRIGGER trigger_inventory_addition
AFTER INSERT ON Inventory
FOR EACH ROW
BEGIN
    dbms_output.put_line('enlisted new phones in database');
    INSERT INTO LogInventoryAddition 
    VALUES(sysdate, :new.phone_id, NULL, :new.quantity);
END;
/

关键修正点说明

  1. 规范行值引用:所有触发行的字段都加上了:new或:old前缀:
    • :new.phone_id:获取当前操作行的phone_id新值(INSERT和UPDATE场景下都有效)
    • :old.price/:old.cost:仅在UPDATE操作时存在有效旧值,INSERT时会自动填充为NULL,符合你的日志表字段定义
  2. 适配INSERT触发器特性:第三个触发器是INSERT触发,没有旧的quantity值,所以日志表的old_quantity用NULL填充,完全匹配你的表结构设计。

执行以上修正后的代码,触发器应该可以正常编译通过。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.09 12:33:11