4

Hello fellow Stackoverflowers,

TLDR: Are MVIEWs using UPDATE or DELETE + INSERT during refresh?

some time ago I ran into an obscure thing when I was fiddling whit materialized views in Oracle. Here is my example:

  • 2 base tables
  • MVIEW logs for both tables
  • PKs for both tables
  • MVIEW created as a join of these base tables
  • PK for MVIEW

Here is an example code:

-- ========================= DDL section =========================

/* drop tables */
drop table tko_mview_test_tb;
drop table tko_mview_test2_tb;

/* drop mview */
drop materialized view tko_mview_test_mv;

/* create tables */
create table tko_mview_test_tb as
  select 1111 as id, 'test' as code, 'hello world' as data, sysdate as timestamp from dual
  union
 select 2222, 'test2' as code, 'foo bar', sysdate - 1 from dual; 
 
create table tko_mview_test2_tb as
  select 1000 as id, 'test' as fk, 'some string' as data, sysdate as timestamp from dual;

/* create table PKs */  
alter table tko_mview_test_tb
  add constraint mview_test_pk
  primary key (id);

alter table tko_mview_test2_tb
  add constraint mview_test2_pk
  primary key (id);

/* create mview logs */
create materialized view log
  on tko_mview_test_tb
  with rowid, (data);
  
create materialized view log
  on tko_mview_test2_tb
  with rowid, (data);
  
/* create mview */
create materialized view tko_mview_test_mv
refresh fast on commit
as select a.code
        , a.data
        , b.data as data_b
        , a.rowid as rowid_a
        , b.rowid as rowid_b 
     from tko_mview_test_tb a
       join tko_mview_test2_tb b on b.fk = a.code;

/* create mview PK */ 
alter table tko_mview_test_mv
  add constraint mview_test3_pk
  primary key (code);    

According to dbms_mview.explain_mview my MVIEW if capable of fast refresh.

Well in this particular case (not in example here) the MVIEW is referenced by an FK from some other table. Because of that, I found out, that when I do a change in one of these base tables and the refresh of MVIEW is triggered I got an error message:

ORA-12048: error encountered while refreshing materialized view "ABC"
ORA-02292: integrity constraint (ABC_FK) violated

I was like What the hell??. So I started digging - I created a trigger on that MVIEW. Something like this:

/* create trigger on MVIEW */  
create or replace trigger tko_test_mview_trg
  after insert or update or delete
  on tko_mview_test_mv
  referencing old as o new as n
  for each row
declare
begin
  if updating then
    dbms_output.put_line('update');
  elsif inserting then
    dbms_output.put_line('insert');
  elsif deleting then
    dbms_output.put_line('delete');
  end if;  
end tko_test_mview_trg;
/

So I was able to see what is happening. According to my trigger, every time I do UPDATE in the base table (not INSERT nor DELETE) there is actually DELETE and INSERT operation on MVIEW table.

update tko_mview_test2_tb
   set data = 'some sting'
 where id = 1000; 
commit;

Output

delete
insert

Is this correct way how refresh of MVIEW works? There is no updates on MVIEW table when refreshing MVIEW?

Regards, Tom

kovalensue
  • 124
  • 11
  • The refresh can use such a method. Try using deferred constraints on the MVIEW, may work (I did not try it) – gsalem Sep 23 '20 at 07:51
  • Hi @gsalem, creating FK constraint which is referencing MVIEW won't help. I've already tried. The problem of this solution is, that when I do the change, constraint check is deffered to end of the transaction (to commit basically), but MVIEW is refreshed on commit. So refresh of MVIEW is new transaction. – kovalensue Sep 23 '20 at 07:56
  • What is probably happening is that the start of the commit flags the FK as 'to be checked'. – gsalem Sep 23 '20 at 09:16
  • Why do you define `code` as PK of the MV when neither `code` nor `fk` are constrained as *unique* in the base tables? – Marmite Bomber Sep 23 '20 at 10:08
  • It's just an example code. Uniqueness is checked by me when I was writing this example code. But this is definitely not relevant to my problem about DML during MVIEW refresh. Actually there is no need to have this PK on MVIEW at all. – kovalensue Sep 23 '20 at 11:13

1 Answers1

5

We have seen the same behavior after upgrading from oracle 12.1 to oracle 19.x

Newly created mviews seems to behave the same, a delete/insert during the refresh instead of the 'expected' update. Not sure if it is bad or wrong.....but it can be 'fixed'.

Apply patch 30781970 (don't forget _fix_control) and recreate the mview.....

Reference: Bug 30781970 - MVIEW REFRESH IS FAILING WITH ORA-1 ERROR WITH TRIGGER PRESENT ON MVIEW (Doc ID 30781970.8)

Dennis
  • 51
  • 1
  • 2
  • This is the correct answer, thanks. However for everyone else please note that Oracle does not officially support triggers on mviews. – user2009267 Aug 25 '22 at 19:23