ORACLE :Vue matérialisée ne fonctionne pas lors de l'Utilisation d'une JOINTURE GAUCHE
-
19-09-2019 - |
Question
Je veux créer une VUE MATÉRIALISÉE à partir d'une JOINTURE GAUCHE de 2 tables.Cependant le suivant me donne une erreur:
SELECT field1
FROM table_1 a
LEFT JOIN table_2 b
ON a.field1=b.field2
ORA-12054:impossible de définir la validation de rafraîchissement de l'attribut de la vue matérialisée
Cependant, les travaux suivants:
SELECT field1
FROM table_1 a, table_2 b
WHERE a.field1=b.field2
Quelqu'un a une idée pourquoi cela se passe.
Merci pour l'aide
La solution
Il y a deux conditions qui ne sont pas satisfaits de faire que de la vue matérialisée de rafraîchissement rapide.La première est que vous ne spécifiez pas le rowid les colonnes de toutes les tables concernées.Et le deuxième est un sans-papiers restriction:ANSI-les jointures ne sont pas pris en charge.
Voici un exemple avec DEPT être table_1, alias et EMP être table_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
Qui imite votre situation.Tout d'abord ajouter le rowid est:
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
Néanmoins, il ne peut pas rafraîchissement rapide, en raison de l'ANSI rejoint.La conversion à l'ancienne syntaxe de jointure externe:
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.
Et pour prouver que cela fonctionne:
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.
L'ANSI-syntaxe de jointure restriction est mentionné dans le point 6 de ce billet de blog.
En ce qui concerne, Rob.
Autres conseils
Puisqu'il s'agit d'un vieux post; Non a mentionné une solution complète.
- Le tableau qui est joint à l'extérieur doit avoir une clé primaire comme mentionné dans Oracle Doc.
- La requête ne devrait pas avoir d'autres contraintes, c'est-à-dire ne devrait avoir aucun critère de filtre dans
WHERE
clause, juste les joints; ne peut pas non plus avoirCASE
/DECODE
déclarationsSELECT
clause;GROUP BY
,SUM()
,COUNT()
et ces tels sont autorisés, cependant.
Dans l'exemple d'exemple ci-dessus, la requête fonctionnera si une clé primaire est créée sur la table du département sur la colonne d'ID de département.
Suivi les instructions suivantes pour faire en sorte que DBMS_MVIEW.EXPLAIN_MVIEW travaille:http://www.sqlsnippets.com/en/topic-12884.html
Capable de:
Refresh_Complete
Pas capable de:
Refresh_fast
Refresh_fast_after_insert
Vue en ligne ou sous-requête dans la liste non prise en charge pour ce type MV
Refresh_fast_after_insert
Vue en ligne ou sous-requête dans la liste non prise en charge pour ce type MV
Refresh_fast_after_insert
Afficher ou sous-requête depuis la liste
Refresh_fast_after_onetab_dml
Voir la raison pour laquelle Refresh_fast_after_insert est désactivé
Mv_report
Refresh_fast_after_any_dml
Voir la raison pour laquelle Refresh_fast_after_onetab_dml est désactivé