我一直在努力让这个查询启动并运行,但继续遇到死胡同,我已阅读了不少论坛,但我无法找到解决方案。 我最初的错误是表突变错误,我知道oracle仍然忙于表,因此无法执行我的第二个任务。基本上我有一个名为project_tbl的表和另一个表,它是该表的副本,名为proj_archive_tbl。我的逻辑是,当project_tbl中名为proj_status的列更改为completed时,它必须将整行插入proj_archive_tbl,然后将project_tbl中的columns_status列更改为'X'。
我的第一次尝试是执行并插入到proj_archive_tbl中的触发器,而不是更新project_tbl delete_status ='X'但是我发现了突变错误。
现在我创建了2个触发器,一个用于在状态更改为在项目表上完成时将数据复制到存档表,另一个触发器,当新行插入到proj_archive_tbl时,将项目delete_status更新为'X'但得到“死锁”在等待资源时检测到“。我已经尝试用数组创建了一个包但我很努力,因为我是oracle的新手,并且还试图遵循asktom推荐,复合触发器和antonomous_transactions但都无济于事。以下是代码,如果有人可以帮助我或以正确的方式指导我,将非常感谢:
create or replace
trigger Arch_Proj_trigger
after update of proj_status on project_tbl
for each row
DECLARE
PRAGMA AUTONOMOUS_TRANSACTION;
begin
if upper(:new.proj_status) = UPPER('completed') then
insert into proj_archive_tbl
values (
:old.proj_code,
:old.proj_name,
:old.cust_code,
:old.proj_manager,
:old.start_date,
:old.end_date,
:old.max_budget,
:new.proj_status,
:old.delete_status);
end if;
commit;
create or replace
trigger Mark_Proj_Deleted
after insert on proj_archive_tbl
for each row
DECLARE
PRAGMA AUTONOMOUS_TRANSACTION;
begin
update project_tbl set delete_status = 'X'
where proj_code = :new.proj_code;
commit;
我希望我使用的是正确的论坛,并提供了足够的信息。 请帮忙! 阿德里安
答案 0 :(得分:2)
这种方法不起作用。以下是造成僵局的原因:
project_tbl
中的行时,您的交易将获得行锁并应用更改arch_proj_trigger
随后会在更新后触发,并在表proj_archive_tbl
中插入一行proj_archive_tbl
表会导致触发器mark_proj_deleted
触发 - 这无法更新project_tbl
中的行,因为原始事务仍然保持其更新时的行锁定状态我一般不支持在触发器中使用这种应用程序逻辑 - 出于上述原因和其他原因。一般来说,如果你开始遇到死锁或突变问题,那么这种方法是错误的。
我的建议是使用PL / SQL过程来执行此类数据操作,并禁止针对表的直接更新语句。至少就是这样,你实现了你需要的控件,一切都简单得多,而且(更重要的是)交易声音。