Skip to Main Content

Breadcrumb

Question and Answer

Tom Kyte

Thanks for the question, Bhavesh.

Asked: September 28, 2000 - 6:59 am UTC

Last updated: August 09, 2006 - 9:52 am UTC

Version: 8i (ver 8.1.5)

Viewed 1000+ times

You Asked

Hello Tom:
I have a problem in ceating MATERIALIZED VIEW.
My goal is, to create a MATERIALIZED VIEW which gives me
the sum of salary of all the employees in deptno = 10.
Here is what commands I issued in user SCOTT:
(I have given GRANT CREATE MATERIALIZED VIEW TO SCOTT; )

SQL> CREATE SNAPSHOT LOG ON emp WITH PRIMARY KEY;

Snapshot log created.

SQL> CREATE MATERIALIZED VIEW mv_1 REFRESH FORCE ON COMMIT
2 AS select sum(sal) as sum_sal from emp
3 where deptno = 10
4 BUILD IMMEDIATE
5 /
BUILD IMMEDIATE
*
ERROR at line 4:
ORA-00933: SQL command not properly ended

SQL> CREATE MATERIALIZED VIEW mv_2 REFRESH on commit
2 AS select sum(sal) as sum_sal from emp
3 where deptno = 10
4 /
AS select sum(sal) as sum_sal from emp
*
ERROR at line 2:
ORA-12051: ON COMMIT attribute is incompatible with other options

SQL> CREATE MATERIALIZED VIEW mv1 REFRESH force
2 AS select sum(sal) as sum_sal from emp
3 where deptno = 10
4 /

Snapshot created.

My Qs are here:
a) Is 1st query required in order to have rest working?
b) Why 2nd and 3rd qry giving problems? It there a syntax
error, or some init.ora parameter setting required?
c) 4th qry worked, but in order to get what I want,
(I want to reflect the changes in the materialized
view immediately, as I change it in emp table)
I need to execute (schedule ?) DBMS_MVIEW.REFRESH()
procedure, right ?
d) Is there any way I can get what I want without
executing (scheduleing) DBMS_MVIEW.REFRESH()
procedure?
e) Do I need to set following 3 init.ora variables in
order to get what I want ?
. QUERY_REWRITE_ENABLED = True
. QUERY_REWRITE_INTEGRITY = enforced
. COMPATIBLE = 8.1.5

Thanks in advance,
Bhavesh



and Tom said...

There are a couple of things here:

o build immediate goes at the "top" of the create command. Before the refresh component.

o if you look at the chart in:
</code> http://docs.oracle.com/cd/A81042_01/DOC/server.816/a76994/mv.htm#42194
it shows that in order to have SUM(SAL), we need to have COUNT(SAL) and that all single table aggregates must have COUNT(*) as well.

o if you look at:
http://docs.oracle.com/cd/A81042_01/DOC/server.816/a76994/mv.htm#32933 <code>

one of the Restrictions on Fast Refresh on Materialized Views with Single-Table Aggregates is they cannot have a WHERE clause.

So, to get what you want -- you cannot "slice" the table that way. You would:


ops$tkyte@ORA8I.WORLD> create table emp as select * from scott.emp
2 /

Table created.

ops$tkyte@ORA8I.WORLD> alter table emp add constraint emp_pk
2 primary key(empno)
3 /

Table altered.

ops$tkyte@ORA8I.WORLD>
ops$tkyte@ORA8I.WORLD> CREATE SNAPSHOT LOG ON emp WITH rowid( sal, deptno )
2 INCLUDING NEW VALUES
3 /

Materialized view log created.

ops$tkyte@ORA8I.WORLD>
ops$tkyte@ORA8I.WORLD>
ops$tkyte@ORA8I.WORLD> create materialized view mv_1
2 build immediate
3 refresh force on commit
4 as
5 select deptno, count(*) cnt1, count(e.sal) cnt2, sum(e.sal) as sum_sal
6 from emp e
7 group by deptno
8 /

Materialized view created.


Now, another approach would be to create an MV of an MV. subset the data you want and then aggregate the subset.

Rating

  (10 ratings)

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

Comments

materialized view

sathyamurthy.s, May 07, 2002 - 2:14 am UTC

Hi
i am using oracle 8i , i want to create materialized view.

but it is giving the problem .

i am giving the script

create table t1 (a int,b int, y number,primary key(a,b));

Table created.

create materialized view log on t1 with rowid(a,y) including new values;

Materialized view log created.

create materialized view t2
build immediate
refresh force on commit
as
select dno, sum(sal)
as sum_sal
from emp
group by dno

cannot set the ON COMMIT refresh attribute for the materialized view

what is the problem please give solutions
Regards

sathya

Tom Kyte
May 07, 2002 - 7:22 am UTC

Please re-read my answer to the original question.

Pay close attention to second point I make about including "sum(sal)"

MATERIALIZED VIEW

sathyamurthy, May 07, 2002 - 8:23 am UTC

Hi Tom,

After adding count in the query it is working fine.

Thanks to you.






How to know ?

Raman Pujani, June 14, 2002 - 4:50 am UTC

Hi Tom,

Nice explanation. How do we come to know whether the query executed by user is actually using the materialized view, means user's query is rewrited ?

Is it true that, we should not include joins with SYSDATE (end_date > SYSDATE) while creating materialized view?

Regards,
Raman.

Tom Kyte
June 14, 2002 - 7:25 am UTC

explain plans.

you can explain the query,
you can use autotrace,
you can use (my favorite) sql_trace+tkprof


As for the last part -- think about it. as sysdate is an ever changing thing, the mat. view is out of date the second it finished refreshing.

mat. view , why do i get this

umesh, June 13, 2003 - 8:35 am UTC

1 CREATE SNAPSHOT LOG ON emp WITH rowid( deptno,sal )
2* INCLUDING NEW VALUES
3 /

Materialized view log created.

1 create materialized view t2
2 build immediate
3 refresh force on commit
4 as
5 select deptno, sum(sal)
6 as sum_sal, count( *) cnt
7 from emp
8* group by deptno
scott>/
from emp
*
ERROR at line 7:
ORA-12054: cannot set the ON COMMIT refresh attribute for the materialized view




Tom Kyte
June 13, 2003 - 8:56 am UTC

<b>amazingly, this is exactly the same thing that is addressed in the original question... repitition being the key to sucess....  I'll do it again :) </b>


http://docs.oracle.com/docs/cd/B10501_01/server.920/a96520/mv.htm#42218

That table shows in order to have 

SUM(expr)

You must also include 

COUNT(expr) and COUNT(*)

You do not have COUNT(expr)


ops$tkyte@ORA817DEV> create materialized view emp_mv
  2  build immediate
  3  refresh force on commit
  4  as
  5  select deptno, sum(sal) sum_sal, <b>count(sal) count_sal,</b> count(*) cnt
  6    from emp
  7   group by deptno
  8  /

Materialized view created.

 

query_rewrite_enabled

Tony, July 07, 2003 - 10:46 am UTC

Oracle recommends to set query_rewrite_enabled = true for Mviews but I'm working on mviews created by someone else and the DDL starts like :
CREATE MATERIALIZED VIEW test_mv
PCTFREE 0 TABLESPACE MV_DATA STORAGE (INITIAL 1M NEXT 1M MINEXTENTS 1 MAXEXTENTS UNLIMITED PCTINCREASE 0)
NOLOGGING NOCACHE
BUILD IMMEDIATE
USING INDEX TABLESPACE MV_INDEX STORAGE (INITIAL 1M NEXT 1M MINEXTENTS 1 MAXEXTENTS UNLIMITED PCTINCREASE 0)
REFRESH COMPLETE ON DEMAND
START WITH (TRUNC(SYSDATE) + 1 + (4/24))
NEXT (TRUNC(SYSDATE) + 1 + (4/24) + (1/24))
WITH PRIMARY KEY
USING LOCAL ROLLBACK SEGMENT MV_RB
DISABLE QUERY REWRITE
AS
SELECT sa.sale_num AS sale_number,
sa.sale_desc AS sale_type,
or.cust_cd AS customer_code,
or.item AS item_id,
or.item_desc AS item_description,
...........

my question is why DISABLE QUERY REWRITE is used in this case. (we have some functions used in mviews)

Tom Kyte
July 07, 2003 - 10:55 am UTC

you would have to ask the guy who wrote it why they chose that option (and why they would use a storage clause in this day and age...)

That is true

Tony, July 07, 2003 - 11:23 am UTC

But my dilemma is that this guy is no more working with us and I'm working on mviews for the first time. Any input will be highly appreciated.

Regards

Tom Kyte
July 07, 2003 - 11:40 am UTC

my input is "i have no clue what he was thinking and why he might have not wanted query rewrite enabled"

bharath, July 07, 2003 - 1:44 pm UTC

>>and why they would use a storage clause in this day and >>age...)

what do you mean by that.

Tom Kyte
July 07, 2003 - 2:04 pm UTC

I mean, use locally managed tablespaces and never use initial, next, pctincrease, minextents, maxextents - let it just happen.

ORA-01001: invalid cursor

Kamal Kishore, September 14, 2003 - 11:36 am UTC

Hi Tom,
When I try to create a MVIEW using the UNION query, I get the Invalid Cursor error. Then I re-create the MVIEW without the UNION query, then DROP it, and then when I re-create the MVIEW again with the UNION QUERY, it is successful.

What could be the reason?
Any input will be appreciated.
Thanks,

All tables have MVIEW LOG created on them and SCOTT.BONUS table has ENAME as the PRIMARY KEY.

SQL> create materialized view mview_emp_dept
  2  build immediate
  3  refresh fast on demand
  4  as
  5  select * from scott.emp e
  6  where
  7    exists (select 1 from scott.dept d1
  8            where
  9                d1.deptno = e.deptno)
 10  union
 11  select * from scott.emp e
 12  where
 13    exists (select 1 from scott.bonus b
 14            where
 15                b.ename = e.ename)
 16  /
select * from scott.emp e
                    *
ERROR at line 5:
ORA-01001: invalid cursor
ORA-00600: internal error code, arguments: [21051], [], [], [], [], [], [], []


SQL>
SQL> create materialized view mview_emp_dept
  2  build immediate
  3  refresh fast on demand
  4  as
  5  select * from scott.emp e
  6  where
  7    exists (select 1 from scott.dept d1
  8            where
  9                d1.deptno = e.deptno)
 10  /

Materialized view created.

SQL>
SQL> drop materialized view mview_emp_dept ;

Materialized view dropped.

SQL>
SQL> create materialized view mview_emp_dept
  2  build immediate
  3  refresh fast on demand
  4  as
  5  select * from scott.emp e
  6  where
  7    exists (select 1 from scott.dept d1
  8            where
  9                d1.deptno = e.deptno)
 10  union
 11  select * from scott.emp e
 12  where
 13    exists (select 1 from scott.bonus b
 14            where
 15                b.ename = e.ename)
 16  /

Materialized view created.

SQL>
SQL> disconnect
Disconnected from Oracle9i Enterprise Edition Release 9.2.0.3.0 - Production
With the Partitioning, OLAP and Oracle Data Mining options
JServer Release 9.2.0.3.0 - Production
SQL>
 

materialized view over a database link

vll, December 16, 2003 - 3:37 pm UTC

Tom,

are there any additional restrictions on creating materialized views over a database link? Is it possible to have "refresh fast", "refresh on commit"? Thank you very-very much

Tom Kyte
December 16, 2003 - 5:42 pm UTC

you cannot refresh on commit -- but you can refresh fast, yes (i prefer to call it "refresh incremental" since it can be slower then a complete refresh of course!)

ORA-00600 while creating materialized view.

Udayan Gupt, August 08, 2006 - 11:02 am UTC

Hi Tom,
Well I get a different kind of an error while trying to create a materialized view.
Its the oracle internal error and the first argument is [16608]
This happened when I dropped a materialized view and I want to recreate it using the original script.
The snapshot uses a select query over a dblink, which selects about seventeen thousand records. The query is working fine, but the snapshot does not get created.
Btw, the error message says that the error has occured in the dblink

Tom Kyte
August 09, 2006 - 9:52 am UTC

ora-600
ora-7445
ora-3113

all of those imply "please utilize support"

More to Explore

PL/SQL demos

Check out more PL/SQL tutorials on our LiveSQL tool.

PL/SQL docs

PL/SQL reference manual from the Oracle documentation library