SQL 触发器编译正确但抛出错误

SQL trigger compiles correctly but throws error

我正在尝试创建一个触发器,在添加新行时将值从一列("notubes" 复制到相同 table 的另一列("notubesleft")。触发器已正确编译,但当我插入新行时,它会抛出错误。

我的触发器是:

create or replace TRIGGER NOTUBESLEFT_INSERT_TRIGGER    
AFTER INSERT ON SAMPLES FOR EACH ROW BEGIN 
update samples
 set notubesleft = (select notubes from samples where sampleid = :new.sampleid);
 END;

当我尝试提交新行时出现错误:

One error saving changes to table "APEX_WS_PROMETHEUS"."SAMPLES":
Row 10: ORA-04091: table APEX_WS_PROMETHEUS.SAMPLES is mutating, trigger/function may not see it
ORA-06512: at "APEX_WS_PROMETHEUS.NOTUBESLEFT_INSERT_TRIGGER", line 2 ORA-04088: error during execution of trigger 'APEX_WS_PROMETHEUS.NOTUBESLEFT_INSERT_TRIGGER'
ORA-06512: at line 1

我问了一个新问题,因为我可以找到有关如何构造触发器的 PL/SQL 代码的解决方案,但我无法弄清楚为什么它不起作用。

谢谢。

您遇到了变异 table 问题。有一个限制,您不能查询在 FOR EACH ROW 触发器

中发生变化的 table

Trigger Restrictions on Mutating Tables

If you must update a mutating table, you can bypass these restrictions by using a temporary table, a PL/SQL table, or a package variable. For example, in place of a single AFTER row trigger that updates the original table, resulting in a mutating table error, you might use two triggers—an AFTER row trigger that updates a temporary table, and an AFTER statement trigger that updates the original table with the values from the temporary table.

您不能(轻松地)查询要使用行级触发器插入的 table。但是您根本不应该查询 table ,也不应该使用插入后触发器来执行此操作。改用插入前触发器;您可以从 :NEW 伪记录中获取和设置值:

CREATE OR REPLACE TRIGGER NOTUBESLEFT_INSERT_TRIGGER    
BEFORE INSERT ON SAMPLES FOR EACH ROW
BEGIN 
  :new.notubesleft := :new.notubes;
END;