假设我有一个如下表--
create table employees
(
eno number(4) not null primary key,
ename varchar2(30),
zip number(5) references zipcodes,
hdate date
);
我使用以下代码块创建了一个触发器
create or replace TRIGGER COPY_LAST_ONO
AFTER INSERT ON ORDERS
FOR EACH ROW
DECLARE
ID_FROM_ORDER_TABLE VARCHAR2(10);
BEGIN
SELECT MAX(ORDERS.ONO)INTO ID_FROM_ORDER_TABLE from ORDERS ;
DBMS_OUTPUT.PUT_LINE(ID_FROM_ORDER_TABLE);
INSERT INTO BACKUP_ONO VALUES( VALUE1, VALUE2,VALUE3, ID_FROM_ORDER_TABLE);
END;
触发器在插入后触发,并尝试从触发它的表中读取(逻辑上是废话!),但 Oracle 给我一个错误,并要求我修改触发器,以便它不读取表。错误代码-
Error report -
SQL Error: ORA-04091: table TEST1.ORDERS is mutating, trigger/function may not see it
ORA-06512: at "TEST1.COPY_LAST_ONO", line 8
ORA-04088: error during execution of trigger 'TEST1.LOG_INSERT'
04091. 00000 - "table %s.%s is mutating, trigger/function may not see it"
*Cause: A trigger (or a user defined plsql function that is referenced in
this statement) attempted to look at (or modify) a table that was
in the middle of being modified by the statement which fired it.
*Action: Rewrite the trigger (or function) so it does not read that table.
我试图用这个触发器实现的是复制最后一个INSERTED
ONO
(这是ORDER
的主键)表)在INSERTED
后立即转移到另一个表。我不明白的是,为什么甲骨文会提示?触发器正在尝试读取AFTER
插入!
想法?解决方案?
非常感谢
最佳答案
如果您尝试记录刚刚插入的 ONO,请使用 :new.ono
并完全跳过选择:
INSERT INTO BACKUP_ONO VALUES( VALUE1, VALUE2,VALUE3, :new.ono);
我不相信您可以从正在插入的表中进行选择,因为尚未发出提交,因此会出现变异表错误。
附注考虑不缩写。向下一个开发人员明确说明并将其命名为 ORDER_NUMBER 或至少是一个普遍接受的缩写(例如 ORDER_NBR),无论您公司的命名标准是什么。 :-)
仅供引用 - 如果您正在更新,您也可以访问 :OLD.column,即更新之前的值(当然,如果该列不是主键列)。
关于oracle - 触发器被同一个表触发后无法读取该表,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34362598/