Skip to Main Content
  • Questions
  • Materialized view refresh in case of DDL on base table, like truncate, drop and recreate

Breadcrumb

Question and Answer

Chris Saxon

Thanks for the question, Anish.

Asked: March 27, 2018 - 5:14 am UTC

Last updated: March 27, 2018 - 5:00 pm UTC

Version: 11g

Viewed 1000+ times

You Asked

Hi Tom,

I was trying to prepare materialized view against some table which are periodically dropped and recreated. I did not find an option to automatically refresh the materialized view in this case. Refresh FAST ON COMMIT is not working, and REFRESH ON DEMAND with start time is not working as well. Can you please suggest if it is possible and if yes, how? It would be great if you could help with this!

Example codes:

CREATE TABLE test_table (ID VARCHAR2(20) PRIMARY KEY);

INSERT INTO test_table VALUES ('1');
INSERT INTO test_table VALUES ('2');
INSERT INTO test_table VALUES ('3');

COMMIT;

CREATE MATERIALIZED VIEW LOG ON test_table;

CREATE MATERIALIZED VIEW test_table_mv
BUILD IMMEDIATE
REFRESH FAST ON COMMIT
AS
SELECT * FROM test_table;

SELECT * FROM test_table_mv; --3 rows selected

TRUNCATE TABLE test_table;

SELECT * FROM test_table_mv;  --again 3 rows selected


and Chris said...

Well, truncating will refresh the MV with any outstanding changes up to that point:

CREATE TABLE test_table (ID VARCHAR2(20) PRIMARY KEY);

INSERT INTO test_table VALUES ('1');
INSERT INTO test_table VALUES ('2');
INSERT INTO test_table VALUES ('3');

COMMIT;

CREATE MATERIALIZED VIEW LOG ON test_table;

CREATE MATERIALIZED VIEW test_table_mv
BUILD IMMEDIATE
REFRESH FAST ON COMMIT
AS
SELECT * FROM test_table;

SELECT * FROM test_table_mv;

ID   
1    
2    
3 

insert into test_table values (4);

TRUNCATE TABLE test_table;

SELECT * FROM test_table_mv; 

ID   
1    
2    
3    
4   


But as you say, it won't remove the existing rows.

Try to fast refresh it and you'll see why:

exec dbms_mview.refresh('test_table_mv', 'F');

ORA-32321: REFRESH FAST of "CHRIS"."TEST_TABLE_MV" unsupported after detail table TRUNCATE


The operation isn't supported! The problem is truncate bypasses the materialized view log. So there are no delete entries to tell the database what's happened.

Of course, if you've just truncated a table then presumably the MV has no rows in it too! So a complete refresh should be nice and quick. After which you're on your way again:

exec dbms_mview.refresh('test_table_mv', 'C');
insert into test_table values (5);
commit;

select * from test_table_mv;

ID   
5   


Similarly, when you drop and recreate a table you've severed the link between the MV and the table. And the MV log is gone too!

Though once again, all you need is a complete refresh to be back in action:

drop table test_table cascade constraints purge;
CREATE TABLE test_table (ID VARCHAR2(20) PRIMARY KEY);
CREATE MATERIALIZED VIEW LOG ON test_table;

exec dbms_mview.refresh('test_table_mv', 'C');
insert into test_table values (6);
commit;

select * from test_table_mv;

ID   
6 

Rating

  (1 rating)

Is this answer out of date? If it is, please let us know via a Comment

Comments

Alex A, March 27, 2018 - 3:08 pm UTC

The real question is why are you dropping and recreating tables regularly, I think.
Chris Saxon
March 27, 2018 - 5:00 pm UTC

Well, yes. That is a good question!

More to Explore

Design

New to good database design? Check out Chris Saxon's full fundamentals class.