【发布时间】:2021-08-30 12:35:51
【问题描述】:
我尝试按行触发器从另一个表更新一个表,但它有问题。
在我添加 PRAGMA AUTONOMOUS_TRANSACTION.. 后触发器工作。但工作方式很奇怪。
Oracle 版本 12c。 我有一个类似的(简化的)代码:
create table w_mutating2 (id number);
insert into w_mutating1 values (NULL); commit;
create or replace trigger w_mutate_trg1
before insert on w_mutating2
for each row
declare
pragma autonomous_transaction;
begin
update w_mutating1 set num = (select max(id) from w_mutating2);
commit;
end;
/
insert into w_mutating2 values (2);
commit;
select * from w_mutating1;
select * from w_mutating2;
之后我的表 w_mutating1 的值为 NULL。 所以我再次执行它
insert into w_mutating2 values (5);
commit;
select * from w_mutating1;
select * from w_mutating2;
我的表 w_mutating 有值 => 2 所以我的触发器起作用了..但是一次操作太晚了;) 在我的复杂示例中,我在类似的触发器中使用函数。 当我从命令行使用参数执行函数时,它可以工作。数据没问题。 但是当我从触发器(使用 PRAGMA 自治事务)执行它时,它会如上所述更新我的数据。
有什么办法解决吗?
【问题讨论】:
-
我不太明白这里有什么问题,你认为什么不起作用。您希望 oracle 在第一次插入时更新 null 吗?我和你一样跑,并且工作正常。
-
pragma autonomous_transaction表示在单独的事务中执行(就像在另一个会话中完成一样),因此在提交之前它看不到新值。但是为什么不按顺序填充id?那么你就不需要查询表来找到最大值了。 -
不要那样做。阅读有关处理变异问题的复合触发器
-
@RobertoHernandez 我希望在我插入第一个提交的值后,触发器会发现它作为最大元素并更新我的第二个表,但我仍然有“null”。在我插入下一行( id = 5 )并提交后,我的第二个表将更新为 id = 1 ,而不是我预期的 id = 5
-
您可能根本不需要触发器或第二个表,只需要一个序列。请使用您尝试使用此解决方案解决的问题来编辑您的问题。 @WilliamRobertson 已经解释了为什么这不会给你任何有用的东西。