2011-09-20 12 views
12

Quando eseguo il seguente codice su Oracle 10g:Oracle vista materializzata errore: codice incluso

drop materialized view test4; 
drop materialized view test3; 
drop table test2; 
drop table test1; 

create table test1 
(
    x1 varchar2(1000), 
    constraint test1_pk primary key (x1) 
); 

create materialized view log on test1 with sequence; 

create table test2 
(
    x2 varchar2(1000), 
    constraint test2_pk primary key (x2) 
); 

create materialized view log on test2 with sequence; 

create materialized view test3 
refresh complete on demand 
as 
(
    select x1 from test1 
    union all 
    select null from dual where 0 = 1 
); 

alter table test3 add constraint test3_pk primary key (x1); 

create materialized view log on test3 with sequence; 

create materialized view test4 
refresh fast on commit 
as 
(
    select t1.rowid as rid1, t2.rowid as rid2, t1.x1 u1, t2.x2 
    from test3 t1, test2 t2 
    where t1.x1 = t2.x2 
); 

ottengo questo errore sul tentativo di creare la vista materializzata test4:

SQL Error: ORA-12053: this is not a valid nested materialized view 
12053. 00000 - "this is not a valid nested materialized view" 
*Cause: The list of objects in the FROM clause of the definition of this 
      materialized view had some dependencies upon each other. 
*Action: Refer to the documentation to see which types of nesting are valid. 

I don' t capire come uno qualsiasi degli oggetti nella "clausola FROM" dipende l'uno dall'altro.

Come posso farlo funzionare? Attualmente l'unico lavoro che posso immaginare è quello di sostituire test3 con una tabella ordinaria e cancellare e aggiornare manualmente i dati. Questo approccio funziona, ma sembra un po 'un trucco.

In alternativa (e forse preferibilmente) vorrei solo vedere un esempio in cui possono avere due tabelle e unirle in una vista materializzata, in cui una delle tabelle di base viene aggiornata in blocco (e non è necessario che venga riflessa nella vista materializzata) ma gli altri aggiornamenti dovrebbero riflettersi nella vista materializzata (ovvero è una specie di "metà" fast refresh on commit e metà complete refresh on demand). Ho provato a utilizzare refresh force, ma quando si utilizza EXECUTE DBMS_MVIEW.EXPLAIN_MVIEW() non ho trovato alcuna prova di aggiornamento fash sul commit disponibile. Mi piacerebbe anche farlo con union all s.

+0

+1 meglio spiegato e ora ilustrated :) –

+0

'test3' non ha molto senso:' seleziona null da duale dove 0 = 1' non restituirà mai una riga. – Allan

+0

@ Allan: questo è un trucco per trasformarlo in un aggregato. Sentiti libero di rimuoverlo se interrompe l'errore. – Clinton

risposta

2

Citando Oracle

Restrictions for Using Multitier Materialized Views

Both master materialized views and materialized views based on materialized views must:

  • Be primary key materialized views
  • Reside in a database that is at 9.0.1 or higher compatibility level

Note: The COMPATIBLE initialization parameter controls a database's compatibility level.

Tuttavia, cercherò una soluzione per voi. Tornerò.

Aggiornamento: Mi dispiace non sono riuscito. Avete troppe restrizioni :)

+0

"Troppe restrizioni"? Cosa intendi? Quali sono le mie restrizioni? – Clinton

+0

il complesso mv (whith union all), un "bulk refreshed" (aggiornamento completo) ... –

0

Si può essere fuori di fortuna, per la documentazione di Oracle:

http://download.oracle.com/docs/cd/B28359_01/server.111/b28313/basicmv.htm#i1006734

You can create a nested materialized view on materialized views, but all parent and base materialized views must contain joins or aggregates. If the defining queries for a materialized view do not contain joins or aggregates, it cannot be nested. All the underlying objects (materialized views or tables) on which the materialized view is defined must have a materialized view log. All the underlying objects are treated as if they were tables. In addition, you can use all the existing options for materialized views.

3

È possibile effettuare la test4 vista materializzata rinfrescare veloce come questo:

SQL> create table test1 
    2 (x1 varchar2(1000) 
    3 , constraint test1_pk primary key (x1) 
    4 ) 
    5/

Table created. 

SQL> create materialized view log on test1 with rowid 
    2/

Materialized view log created. 

SQL> create table test2 
    2 (x2 varchar2(1000) 
    3 , constraint test2_pk primary key (x2) 
    4 ) 
    5/

Table created. 

SQL> create materialized view log on test2 with rowid 
    2/

Materialized view log created. 

SQL> create materialized view test4 
    2 refresh fast on commit 
    3 as 
    4 select t1.rowid as rid1 
    5   , t2.rowid as rid2 
    6   , t1.x1 u1 
    7   , t2.x2 
    8  from test1 t1 
    9   , test2 t2 
10  where t1.x1 = t2.x2 
11/

Materialized view created. 

SQL> insert into test1 values ('hello') 
    2/

1 row created. 

SQL> insert into test2 values ('hello') 
    2/

1 row created. 

SQL> commit 
    2/

Commit complete. 

SQL> select * from test4 
    2/

RID1    RID2 
------------------ ------------------ 
U1 
--------------------------------------------- 
X2 
--------------------------------------------- 
AAATU5AAEAAAssfAAA AAATU8AAEAAAssvAAA 
hello 
hello 


1 row selected. 

Il tuo caso non funziona perché una MV annidata funziona, una MV sottostante non può essere una MV di base. All'inizio sembra strano, ma avresti bisogno di un trucco come hai fatto con test3 per farlo funzionare. Inoltre, affinché un join MV funzioni, è necessario creare i registri di visualizzazione materializzati della tabella sottostante WITH ROWID.

Si potrebbe voler guardare una serie di post sul blog che ho scritto sugli errori di visualizzazione materializzati veloci aggiornabili. Essi descrivono quasi tutte le restrizioni:

Basic MV's
Join MV's
Aggregate MV's
Union all MV's
Nested MV's
MV_CAPABILITIES_TABLE
Summary

saluti,
Rob.


Aggiunto: 29-09-2011

Ecco un esempio con una MV nidificato utilizzando l'unione tutte trucco su test2 così:

SQL> create table test1 
    2 (x1 varchar2(1000) 
    3 , constraint test1_pk primary key (x1) 
    4 ) 
    5/

Table created. 

SQL> create materialized view log on test1 with rowid 
    2/

Materialized view log created. 

SQL> create table test2 
    2 (x2 varchar2(1000) 
    3 , constraint test2_pk primary key (x2) 
    4 ) 
    5/

Table created. 

SQL> create materialized view log on test2 with rowid 
    2/

Materialized view log created. 

SQL> create materialized view test2_mv 
    2 refresh fast on commit 
    3 as 
    4 select rowid rid 
    5  , x2 
    6  , 'A' umarker 
    7 from test2 
    8 union all 
    9 select rowid 
10  , x2 
11  , 'B' 
12 from test2 
13 where 1=0 
14/

Materialized view created. 

SQL> alter table test2_mv add constraint test2_mv_pk primary key(x2) 
    2/

Table altered. 

SQL> create materialized view log on test2_mv with rowid 
    2/

Materialized view log created. 

SQL> create materialized view test3 
    2 refresh fast on commit 
    3 as 
    4 select rowid rid 
    5  , x1 
    6  , 'A' umarker 
    7 from test1 
    8 union all 
    9 select rowid 
10  , x1 
11  , 'B' 
12 from test1 
13 where 0 = 1 
14/

Materialized view created. 

SQL> alter table test3 add constraint test3_pk primary key (x1) 
    2/

Table altered. 

SQL> create materialized view log on test3 with rowid 
    2/

Materialized view log created. 

SQL> create materialized view test4 
    2 refresh fast on commit 
    3 as 
    4 select t1.rowid as rid1 
    5   , t2.rowid as rid2 
    6   , t1.x1 u1 
    7   , t2.x2 
    8  from test3 t1 
    9   , test2_mv t2 
10  where t1.x1 = t2.x2 
11/

Materialized view created. 

SQL> insert into test1 values ('hello') 
    2/

1 row created. 

SQL> insert into test2 values ('hello') 
    2/

1 row created. 

SQL> commit 
    2/

Commit complete. 

SQL> select * from test4 
    2/

RID1    RID2 
------------------ ------------------ 
U1 
--------------------------------------------------- 
X2 
--------------------------------------------------- 
AAATXbAAEAAAstdAAA AAATXXAAEAAAstNAAA 
hello 
hello 


1 row selected. 

Spero che questo aiuti!

+0

"Questo suona strano all'inizio, ma avresti bisogno di un trucco come hai fatto con test3 per farlo funzionare": La tua risposta ha dato solo il codice per basare una vista materializzata su due tabelle, cosa che posso già fare. Puoi darmi un codice di esempio con questo trucco che mi consente di basare una vista di aggiornamento veloce su un aggiornamento completo su richiesta? – Clinton

+0

La soluzione dipende dal modo in cui appare la tua completa visualizzazione di aggiornamento. È una MV di base, join, aggregata, unione o nidificata? Nel tuo esempio, la MV test3 non è necessaria. –

+0

Oppure il tuo test3 MV non è stato concepito come un trucco per renderlo un sindacato MV piuttosto che un MV di base, mi chiedo ... –

Problemi correlati