【问题标题】:Oracle trigger to refresh materialised view is giving delayed output in materialised viewOracle 刷新物化视图的触发器在物化视图中给出延迟输出
【发布时间】:2021-07-16 20:54:14
【问题描述】:

我们制作了一个名为“Complaint_view”的物化视图。每当在“投诉”表上执行插入、删除或更新时,我们都希望刷新此视图。我们使用以下代码来制作视图...

create materialized view complaint_view 
build immediate
refresh complete
on demand
as
select t1.Complaint_ID,Status,C_TimeStamp,Description,House_No,Owner_name,Staff_ID,Staff_name from
(select Complaint_ID,Status,C_TimeStamp,Description,Complaint.House_No,Person.Name as Owner_name 
from Complaint
join House
on Complaint.House_No = House.House_No
join Person 
on House.Owner_ID = Person.Person_Id) t1
left outer join
(select Complaint_ID,Complaint.Staff_ID, Person.Name as Staff_name
from Complaint
join Person
on Complaint.Staff_ID = Person.Person_ID) t2
on t1.Complaint_ID = t2.Complaint_ID;

select 语句是有目的的,它也使用其他表。

我为它做了以下触发器

create or replace trigger refresh_comp_view
after insert or update or delete on Complaint 
DECLARE    
   PRAGMA AUTONOMOUS_TRANSACTION; 
begin
dbms_mview.refresh(LIST=>'complaint_view');
commit;
end refresh_comp_view;

当我更新投诉表时,视图会更新,但之前的更新会被存储。

例如,如果我首先将列更新为“123”,然后再次更新为“1234567”,那么在物化视图中,我将得到“123”而不是“1234567”。

这里有什么问题?为什么要在物化视图中更新以前的值?

【问题讨论】:

  • 会不会是因为你的触发器是BEFORE INSERT OR ...触发器?在执行实际语句之前触发该触发器。尝试将其更改为AFTER INSERT OR ...
  • 另外,触发器中不需要提交,但我会重新考虑我的架构......这可能会导致严重的性能问题。
  • afterbefore 发生了同样的事情。

标签: sql database oracle plsql oracle11g


【解决方案1】:

首先,听起来你想要的是on commit materialized view。这将要求您在基表上有适当的物化视图日志。但是由于您的物化视图定义似乎只包含连接,因此我看不出有任何明显的原因表明它不能作为提交时的增量刷新来完成。

至于您的实际问题,忽略每次数据更改时进行完全刷新的效率低下以及需要为引用的其他表复制此触发器,问题在于触发器是一个自治事务。这意味着它与执行 DML 的事务分开完成,并且它必须在 DML 事务完成之前完成。因此,dbms_mview.refresh 调用在运行时会看到表的已提交状态,这必然会排除导致触发器触发的打开事务。因此,刷新在运行时看到的是已提交的值 123,而不是当前未提交的值 1234567。

如果您出于某种原因真的非常想保留当前架构,您会希望触发器提交一个仅在当前事务提交后才进行刷新的作业。您需要确保触发器不是自治事务,以确保作业在当前事务提交后的某个时间才开始。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2012-07-04
    • 1970-01-01
    • 1970-01-01
    • 2021-10-11
    • 2016-12-09
    • 2012-07-18
    • 2016-06-14
    • 2010-09-27
    相关资源
    最近更新 更多