Skip to Main Content
  • Questions
  • How to update a materialized view directly

Breadcrumb

Question and Answer

Chris Saxon

Thanks for the question, Mansi.

Asked: June 18, 2017 - 7:17 pm UTC

Last updated: February 03, 2021 - 2:21 pm UTC

Version: 11.2.0.4

Viewed 50K+ times! This question is

You Asked

Hi

Can we update data in Materialized view directly using update statement. If yes,will that updated to table as well. What if there are more than one table in view?

Please help me on this.



and Chris said...

By default, no. Materialized views aren't updatable:

create table t (
  x int primary key, y int
);

insert into t values (1, 1);
insert into t values (2, 2);
commit;

create materialized view log on t including new values;

create materialized view mv 
refresh fast with primary key 
as 
  select * from t;
  
update mv
set    y = 3;

ORA-01732: data manipulation operation not legal on this view


But you can use the "for update" clause to change the data in an MV:

drop materialized view mv ;

create materialized view mv 
refresh fast with primary key for update 
as 
  select * from t;
  
update mv
set    y = 3;

insert into mv values (3, 3);

select * from mv;

         X          Y
---------- ----------
         1          3
         2          3
         3          3

select * from t;

         X          Y
---------- ----------
         1          1
         2          2


Note that the changes aren't pushed to the base table. As soon as you refresh it, the changes are lost:

exec dbms_mview.refresh('mv');

select * from mv;

         X          Y
---------- ----------
         1          1
         2          2


So, how do you push changes to the base table?

The short answer is you can't. This part of Advanced Replication. It's for pushing changes from a remote DB to the master. This is deprecated in 12.1

https://docs.oracle.com/database/121/REPMA/release_changes.htm#REPMA1356

So I wouldn't recommend using this. If you really want to, you can find a worked example at:

http://www.vinayagaconsultancyltd.co.uk/blogs/advanced-replication/updatable-materialized-view

Or you can read MOS note 759196.1. This gives a detailed description of how the process works. Including what happens if you write conflicting changes to the table and MV!

Rating

  (9 ratings)

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

Comments

Mansi Raval, June 21, 2017 - 9:02 am UTC

Thank you so much Chris.

Thanks for the examples and links.

updating Materialized view

sankar, July 11, 2017 - 12:03 pm UTC

use below code to update materialized view when base table has having new rows.. this is only for updating materialized view from base table to materialized view.
create materialized view mv
here use on commit is refresh table automatically for mannual use on demand..
refresh fast with primary key for update on commit
as
select * from t;

update mv
set y = 3;

insert into mv values (3, 3);

select * from mv;

X Y
---------- ----------
1 3
2 3
3 3

select * from t;

X Y
---------- ----------
1 1
2 2
Chris Saxon
July 11, 2017 - 2:31 pm UTC

I'm not following what you're doing, could you clarify please?

The updates and insert can be captured..

Ron, July 24, 2018 - 4:40 pm UTC

create materialized view on pre-built table.
create a trigger on the pre-built table
to capture inserts and updates.
and then the captured data could be updated or inserted
on the base table and then when mview is refreshed it wont be lost.
The inserts could be done thru batch or dbms_Scheduler on base.
Chris Saxon
July 26, 2018 - 10:41 am UTC

What are you trying to achieve by doing this? What's the end goal here?

And what's the exact code you're running?

A reader, January 20, 2019 - 9:51 am UTC


keep data when updating materialized view

Arnold, January 25, 2019 - 10:37 am UTC

dear Chris,
To keep the data in the underlying table and change them (in 11.2) use:
drop materialized view mv preserve table;
update mv set y = 3;
commit;
You reinstall the materialized view by adding 'on prebuilt table' as follows:
create materialized view mv on prebuilt table refresh fast with primary key as select * from t;
So, the mv is again not updatable.

Below is the whole procedure. Thanks for this great site.
prompt remove previous experiment (dropping the table mv probably is not needed)
drop table t;
drop materialized view mv;
drop table mv;
prompt as before

create table t ( x int primary key, y int );
insert into t values (1, 1);
insert into t values (2, 2);
commit;

create materialized view log on t including new values;

create materialized view mv refresh fast with primary key as select * from t;


prompt there are two database objects for mv:
select object_type from all_objects where object_name='MV';

prompt drop the materialized view, not the underlying table
drop materialized view mv preserve table;

prompt only the table for mv is left:
select object_type from all_objects where object_name='MV';

prompt adapt mv
update mv set y = 3;
commit;

prompt see what is in the table mv now:
select * from mv;

prompt reinstall the mv with exactly the same syntax and 'on prebuilt table' added:
create materialized view mv on prebuilt table refresh fast with primary key as select * from t;

prompt there are two database objects again for mv:
select object_type from all_objects where object_name='MV';

prompt the mv is again not updatable (error)
update mv set y = 4;


prompt remove all: as the materialized view has a prebuilt table, which needs to be removed separately:
drop materialized view mv;
drop table mv;
drop table t;

Chris Saxon
February 04, 2019 - 1:48 pm UTC

Thanks for sharing - though this is a bit convoluted; it wouldn't be my first choice...

from Create Mview Syntax

Rajeshwaran, Jeyabal, February 14, 2019 - 10:10 am UTC

Team,

was looking into the product docs for the "refresh fast with primary key for update" by dont see that available.

https://docs.oracle.com/en/database/oracle/oracle-database/12.2/sqlrf/CREATE-MATERIALIZED-VIEW.html#GUID-EE262CA4-01E5-4618-B659-6165D993CA1B

kindly advice, where it is mentioned in the docs.
Chris Saxon
February 14, 2019 - 11:08 am UTC

That's because it was deprecated in 12.1. You'll find it in the docs for that release:

https://docs.oracle.com/database/121/SQLRF/statements_6002.htm#SQLRF01302

syntax

Sunny, February 03, 2021 - 6:47 am UTC

why materialized view does not have "replace" option?
any logic behind this?
Chris Saxon
February 03, 2021 - 2:21 pm UTC

What do you mean exactly? Please clarify!

why materialized view does not have "replace" option?

A reader, February 04, 2021 - 8:18 am UTC


Same reason a table does not create or replace.

Mviews are not simple views but have a table to hold the data as well (replication).

Hope it clarifies.

Cheers.

thank you

A reader, February 07, 2024 - 4:23 am UTC


More to Explore

DBMS_MVIEW

More on PL/SQL routine DBMS_MVIEW here