创建多个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; /
关键修正点说明
- 规范行值引用:所有触发行的字段都加上了
:new或:old前缀::new.phone_id:获取当前操作行的phone_id新值(INSERT和UPDATE场景下都有效):old.price/:old.cost:仅在UPDATE操作时存在有效旧值,INSERT时会自动填充为NULL,符合你的日志表字段定义
- 适配INSERT触发器特性:第三个触发器是INSERT触发,没有旧的quantity值,所以日志表的
old_quantity用NULL填充,完全匹配你的表结构设计。
执行以上修正后的代码,触发器应该可以正常编译通过。
内容的提问来源于stack exchange,提问作者ganjaam
相关产品推荐
相关产品推荐

