Oracle PL/SQL触发器:在update语句后自动重置列值
出于测试目的,我希望将以下场景自动化:Oracle PL/SQL触发器:在update语句后自动重置列值,sql,oracle,plsql,triggers,oracle12c,Sql,Oracle,Plsql,Triggers,Oracle12c,出于测试目的,我希望将以下场景自动化: 将我的表的列状态设置为已关闭的值(使用update语句) 提交更新,以便其他用户可以看到状态的新值 等待1分钟 将我的表格的列状态重置为其原始值init(使用触发器) 提交更新,以便其他用户可以看到状态的原始值 我试过用这个扳机,但不起作用 ORA-04091:表名正在变化,触发器/函数可能看不到它 既然不允许在触发器内提交,那么还有其他方法可以解决这个问题吗?使用基于事件的作业?这似乎是个坏主意睡眠()触发器内部?这只会增加锁并占用资源 相反,您可以使用
既然不允许在触发器内提交,那么还有其他方法可以解决这个问题吗?使用基于事件的作业?这似乎是个坏主意<代码>睡眠()触发器内部?这只会增加锁并占用资源 相反,您可以使用视图或虚拟列。将
closeDate
存储为表中的一列(如果愿意,可以使用触发器进行设置)
要将其作为作业运行,您需要一个可以调用的过程。我假定您希望对特定记录执行此操作,而不是对整个表执行此操作,因此使用ID参数
create or replace procedure reset_my_table_status
( p_id in number )
is
begin
update my_table
set status = 'INIT'
where id = p_id;
commit;
end;
/
然后,从触发器提交作业,在60秒后调用该过程:
CREATE OR REPLACE TRIGGER RESET_COLUMN
AFTER UPDATE OF STATUS ON MY_TABLE
FOR EACH ROW
WHEN (NEW.STATUS != 'INIT')
DECLARE
jn number;
pragma autonomous_transaction;
BEGIN
dbms_job.submit(jn
, what=>'reset_my_table_status('||:new.id||');'
, next_date => sysdate + 60/86400
);
commit;
END;
/
设置next\u date
参数意味着作业将在60秒内触发,因此无需调用sleep()。请记住,要运行作业,需要作业队列进程init参数的值大于0。我们必须承诺提交一份工作;所以我们需要一个自治事务,因为通常我们不能从触发器发出提交
或者,您可以只构建一个过程(甚至是一个匿名块)
然后,只需对要测试的ID运行该过程 :new.status:='INIT'
并从触发器中删除commit
。触发器中不能有任何事务处理,但我需要提交这些事务,以便其他用户可以使用它们。请查看已编辑的问题摘要,但在我的情况下,修改表格结构不是一个选项。@nogc。视图不是对表结构的修改(虚拟列是,但不是视图)。非常感谢。它按预期工作,但我需要在what=>'reset_my_table_status(“| |:new.id | |”)中添加一个分号代码>否则我会得到Oracle-PLS-00103。请看OOPS。很抱歉。
create or replace procedure reset_my_table_status
( p_id in number )
is
begin
update my_table
set status = 'INIT'
where id = p_id;
commit;
end;
/
CREATE OR REPLACE TRIGGER RESET_COLUMN
AFTER UPDATE OF STATUS ON MY_TABLE
FOR EACH ROW
WHEN (NEW.STATUS != 'INIT')
DECLARE
jn number;
pragma autonomous_transaction;
BEGIN
dbms_job.submit(jn
, what=>'reset_my_table_status('||:new.id||');'
, next_date => sysdate + 60/86400
);
commit;
END;
/
create or replace procedure my_table_status_test
( p_id in number )
is
begin
update my_table
set status = 'MEH'
where id = p_id;
commit;
DBMS_LOCK.SLEEP(60);
update my_table
set status = 'INIT'
where id = p_id;
commit;
end;
/