Pergunta

Quero criar uma MATERIALIZED VIEW a partir de um LEFT JOIN de 2 tabelas.No entanto, o seguinte me dá um erro:

    SELECT field1 
     FROM table_1 a 
     LEFT JOIN table_2 b 
     ON a.field1=b.field2

ORA-12054:não é possível definir o atributo de atualização ON COMMIT para a visualização materializada

No entanto, o seguinte funciona:

SELECT field1 
 FROM table_1 a, table_2 b 
 WHERE a.field1=b.field2

Alguém tem alguma idéia de por que isso está acontecendo.

Obrigado pela ajuda

Foi útil?

Solução

Existem duas condições que não são satisfeitas para que a visualização materializada seja atualizada rapidamente.A primeira é que você não especificou as colunas rowid de todas as tabelas envolvidas.E a segunda é uma restrição não documentada:Junções ANSI não são suportadas.

Aqui está um exemplo com DEPT sendo tabela_1, alias a e EMP sendo tabela_2, alias b:

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

Materialized view log created.

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

Materialized view log created.

SQL> create materialized view empdept_mv
  2    refresh fast on commit
  3  as
  4  select a.deptno
  5    from dept a
  6         left join emp b on (a.deptno = b.deptno)
  7  /
  from dept a
       *
ERROR at line 5:
ORA-12054: cannot set the ON COMMIT refresh attribute for the materialized view

Isso imita sua situação.Primeiro adicione o rowid:

SQL> create materialized view empdept_mv
  2    refresh fast on commit
  3  as
  4  select a.rowid dept_rowid
  5       , b.rowid emp_rowid
  6       , a.deptno
  7    from dept a
  8         left join emp b on (a.deptno = b.deptno)
  9  /
  from dept a
       *
ERROR at line 7:
ORA-12054: cannot set the ON COMMIT refresh attribute for the materialized view

Ainda assim, não é possível atualizar rapidamente, devido às junções ANSI.Convertendo para sintaxe de junção externa de estilo antigo:

SQL> create materialized view empdept_mv
  2    refresh fast on commit
  3  as
  4  select a.rowid dept_rowid
  5       , b.rowid emp_rowid
  6       , a.deptno
  7    from dept a
  8       , emp b
  9   where a.deptno = b.deptno (+)
 10  /

Materialized view created.

E para provar que funciona:

SQL> select * from empdept_mv
  2  /

DEPT_ROWID         EMP_ROWID              DEPTNO
------------------ ------------------ ----------
AAARhmAAEAAAAI/AAB AAARhlAAEAAAAI3AAA         20
AAARhmAAEAAAAI/AAC AAARhlAAEAAAAI3AAB         30
AAARhmAAEAAAAI/AAC AAARhlAAEAAAAI3AAC         30
AAARhmAAEAAAAI/AAB AAARhlAAEAAAAI3AAD         20
AAARhmAAEAAAAI/AAC AAARhlAAEAAAAI3AAE         30
AAARhmAAEAAAAI/AAC AAARhlAAEAAAAI3AAF         30
AAARhmAAEAAAAI/AAA AAARhlAAEAAAAI3AAG         10
AAARhmAAEAAAAI/AAB AAARhlAAEAAAAI3AAH         20
AAARhmAAEAAAAI/AAA AAARhlAAEAAAAI3AAI         10
AAARhmAAEAAAAI/AAC AAARhlAAEAAAAI3AAJ         30
AAARhmAAEAAAAI/AAB AAARhlAAEAAAAI3AAK         20
AAARhmAAEAAAAI/AAC AAARhlAAEAAAAI3AAL         30
AAARhmAAEAAAAI/AAB AAARhlAAEAAAAI3AAM         20
AAARhmAAEAAAAI/AAA AAARhlAAEAAAAI3AAN         10
AAARhmAAEAAAAI/AAD                            40

15 rows selected.

SQL> insert into dept values (50,'IT','UTRECHT')
  2  /

1 row created.

SQL> commit
  2  /

Commit complete.

SQL> select * from empdept_mv
  2  /

DEPT_ROWID         EMP_ROWID              DEPTNO
------------------ ------------------ ----------
AAARhmAAEAAAAI/AAB AAARhlAAEAAAAI3AAA         20
AAARhmAAEAAAAI/AAC AAARhlAAEAAAAI3AAB         30
AAARhmAAEAAAAI/AAC AAARhlAAEAAAAI3AAC         30
AAARhmAAEAAAAI/AAB AAARhlAAEAAAAI3AAD         20
AAARhmAAEAAAAI/AAC AAARhlAAEAAAAI3AAE         30
AAARhmAAEAAAAI/AAC AAARhlAAEAAAAI3AAF         30
AAARhmAAEAAAAI/AAA AAARhlAAEAAAAI3AAG         10
AAARhmAAEAAAAI/AAB AAARhlAAEAAAAI3AAH         20
AAARhmAAEAAAAI/AAA AAARhlAAEAAAAI3AAI         10
AAARhmAAEAAAAI/AAC AAARhlAAEAAAAI3AAJ         30
AAARhmAAEAAAAI/AAB AAARhlAAEAAAAI3AAK         20
AAARhmAAEAAAAI/AAC AAARhlAAEAAAAI3AAL         30
AAARhmAAEAAAAI/AAB AAARhlAAEAAAAI3AAM         20
AAARhmAAEAAAAI/AAA AAARhlAAEAAAAI3AAN         10
AAARhmAAEAAAAI/AAD                            40
AAARhmAAEAAAAI7AAA                            50

16 rows selected.

A restrição de sintaxe ANSI-join é mencionada no ponto 6 em esta postagem do blog.

Atenciosamente, Rob.

Outras dicas

Como este é um post antigo; Não mencionou uma solução completa.

  1. A tabela que está unida externa deve ter uma chave primária, conforme mencionado no Oracle Doc.
  2. A consulta não deve ter outras restrições, ou seja, não deve ter nenhum critério de filtro em WHERE Cláusula, apenas as junções; Nem pode ter CASE/DECODE declarações em SELECT cláusula; GROUP BY, SUM(), COUNT() e tal é permitido, no entanto.

No exemplo acima do exemplo, a consulta funcionará se uma chave primária for criada na tabela de departamento na coluna ID do departamento.

Seguiu as seguintes instruções para fazer dbms_mview.explain_mview funcionar:http://www.sqlsnippets.com/en/topic-12884.html

Capaz de:

Refresh_complete

Não é capaz de:

Refresh_fast

Refresh_fast_after_insert
Visualização em linha ou subconstração da lista não suportada para este tipo MV

Refresh_fast_after_insert
Visualização em linha ou subconstração da lista não suportada para este tipo MV

Refresh_fast_after_insert
Visualizar ou subconstar na lista

Refresh_fast_after_onetab_dml
Veja o motivo pelo qual refresh_fast_after_insert está desativado

Mv_report

Refresh_fast_after_any_dml
Veja o motivo pelo qual refresh_fast_after_onetab_dml está desativado

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top