我想要一个更新列值的触发器,但我只想更新一小部分行,这些行取决于插入行的值。 我的触发器是:
CREATE OR REPLACE TRIGGER example
AFTER INSERT ON table1
FOR EACH ROW
BEGIN
UPDATE table1 t
SET column2 = 3
WHERE t.column1 = :new.column1;
END;
/
但是当我使用FOR EACH ROW时,我尝试它时遇到问题,我得到了变异表运行时错误。 其他选项不是设置FOR EACH ROW,但如果我这样做,我不知道插入的“column1”用于比较(或者我不知道如何知道它)。
如何更新依赖于最后插入的行的一组行?
我正在使用Oracle 9。
答案 0 :(得分:3)
评论太长了。
如果您在更新一行时需要更新table1
中的多行,那么您似乎对数据模型有问题。
这种需求表明您需要一个单独的表,每行column1
一行。然后,您可以使用join
获取该表中的值。然后触发器将更新另一个表,因此不存在突变问题。
答案 1 :(得分:2)
您应该避免在触发器中定义的同一个表上的DML语句。使用before
DML更改当前表的值。
create or replace trigger example
before insert on table1
for each row
begin
:new.column2 := 3;
end;
/
您可以使用pragma autonomous_transaction修改同一个表:
create or replace trigger example
after insert on table1 for each row
declare
procedure setValues(key number) is
pragma autonomous_transaction;
begin
update table1 t
set column2 = 3
where t.column1 = key
;
end setValues;
begin
setValues(:new.column1);
end;
/
但我建议你关注@GordonLinoff回答你的问题 - 在触发器体中修改同一个表是个坏主意。
另见here
答案 2 :(得分:0)
`create table A
(
a INTEGER,
b CHAR(10)
);
create table B
(
b CHAR (10),
d INTEGER
);
create trigger trig1
AFTER INSERT ON A
REFERENCING NEW AS newROW
FOR EACH ROW
when(newROW.a<=10)
BEGIN
INSERT into B values(:newROW.b,:newROW.a);
END trig1;
insert into A values(11,'Gananjay');
insert into A values(5,'Hritik');
select * from A;
select * from B;`