我想知道如果在我的oracle数据库正在使用时更换触发器,是否会遗漏任何数据。我创造了一个玩具示例,似乎我不会,但我的一个同事声称不然。
create table test_trigger (id number);
create table test_trigger_h (id number);
create sequence test_trigger_seq;
--/
create or replace trigger test_trigger_t after insert on test_trigger for each row
begin
insert into test_trigger_h (id) values (:new.id);
end;
/
--/
begin
for i in 1..100000 loop
insert into test_trigger (id) values (test_trigger_seq.nextval);
end loop;
end;
/
--/
begin
for i in 1..10000 loop
execute immediate 'create or replace trigger test_trigger_t after insert on test_trigger for each row begin insert into test_trigger_h (id) values (:new.id); end;';
end loop;
end;
/
ran the two loops at the same time
select count(1) from test_trigger;
COUNT(1)
100000
select count(1) from test_trigger_h;
COUNT(1)
100000
答案 0 :(得分:1)
create or replace
正在锁定表格。所以所有插入都会等到它完成。不要担心错过插入。
答案 1 :(得分:0)
我认为你可能会以错误的方式测试它。您的插入语句根本不会花费任何时间,因此触发器的替换可以通过插入之间的间隙来适应。至少这是我推断的原因,如下所示。
如果更改测试以确保具有长时间运行的SQL语句,例如
create table test_trigger (id number);
create table test_trigger_h (id number);
create sequence test_trigger_seq;
create or replace trigger test_trigger_t
after insert on test_trigger for each row
begin
insert into test_trigger_h (id) values (:new.id);
end;
/
insert into test_trigger
select level
from dual
connect by level <= 1000000;
如果您尝试在单独的会话中替换触发器,则在插入完成之后才会发生。
不幸的是,我在文档中找不到任何支持我的内容;这只是我所知道的行为。
答案 2 :(得分:0)
以下网址答案可以在应用程序运行时修改触发器。它将是一个“库缓存”锁而不是“数据”锁。 Oracle在内部处理它而不用担心它。
查看Ben- Can a trigger be locked; how would one determine that it is?
提出的问题- 从会话2运行: select * from v $ access其中object = upper('test_trigger_t');