可以说我有一张桌子如下-
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;
触发器在插入后触发,并尝试从触发它的表中读取(逻辑上是duhh!),但是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.
我要通过此触发器实现的目标是,将begin之后的最后一个INSERTED
ONO
(这是该ORDER
表的主键)立即复制到另一个表中INSERTED
。我不明白的是,为什么甲骨文抱怨呢?触发器正在尝试读取AFTER
插入内容!
有想法吗?解?
非常感谢
如果要记录刚插入的ONO,请完全使用:new.ono
并跳过选择:
INSERT INTO BACKUP_ONO VALUES( VALUE1, VALUE2,VALUE3, :new.ono);
我不相信您可以从插入中间的表中进行选择,因为尚未发出提交,因此发生了变异表错误。
PS请考虑不要缩写。对于下一个开发人员,请明确说明其名称,无论您公司的命名标准如何,都将其命名为ORDER_NUMBER或至少一个公认的缩写,例如ORDER_NBR。:-)
仅供参考-如果您要更新,则还可以访问:OLD.column,即更新前的值(当然,如果该列不是主键列)。