Donc, je suis à peu près sûr que Oracle est d'accord avec ça, donc je n'ai aucune idée de ce que je fais mal. Ce code fonctionne:
CREATE MATERIALIZED VIEW MV_Test
NOLOGGING
CACHE
BUILD IMMEDIATE
REFRESH FAST ON COMMIT
AS
SELECT V.* FROM TPM_PROJECTVERSION V;
Si j'ajoute un JOIN, ça casse:
CREATE MATERIALIZED VIEW MV_Test
NOLOGGING
CACHE
BUILD IMMEDIATE
REFRESH FAST ON COMMIT
AS
SELECT V.*, P.* FROM TPM_PROJECTVERSION V
INNER JOIN TPM_PROJECT P ON P.PROJECTID = V.PROJECTID
Maintenant j'obtiens l'erreur:
ORA-12054: impossible de définir l'attribut d'actualisation ON COMMIT pour la vue matérialisée
J'ai créé des journaux de vue matérialisés à la fois sur TPM_PROJECT et TPM_PROJECTVERSION. TPM_PROJECT a une clé primaire de PROJECTID et TPM_PROJECTVERSION a une clé primaire composée de (PROJECTID, VERSIONID). Quel est le truc pour ça? J'ai fouillé dans les manuels Oracle en vain. Merci!
Pour commencer, à partir du Guide de la base de données Oracle Database Warehousing :
Restrictions sur l'actualisation rapide des vues matérialisées avec des jointures uniquement
...
- Les ID de ligne de toutes les tables de la liste FROM doivent apparaître dans la liste SELECT de la requête.
Cela signifie que votre déclaration devra ressembler à ceci:
CREATE MATERIALIZED VIEW MV_Test
NOLOGGING
CACHE
BUILD IMMEDIATE
REFRESH FAST ON COMMIT
AS
SELECT V.*, P.*, V.ROWID as V_ROWID, P.ROWID as P_ROWID
FROM TPM_PROJECTVERSION V,
TPM_PROJECT P
WHERE P.PROJECTID = V.PROJECTID
Un autre aspect important à noter est que les journaux de votre vue matérialisée doivent être créés en tant que with rowid
.
Vous trouverez ci-dessous un scénario de test fonctionnel:
CREATE TABLE foo(foo NUMBER, CONSTRAINT foo_pk PRIMARY KEY(foo));
CREATE MATERIALIZED VIEW LOG ON foo WITH ROWID;
CREATE TABLE bar(foo NUMBER, bar NUMBER, CONSTRAINT bar_pk PRIMARY KEY(foo, bar));
CREATE MATERIALIZED VIEW LOG ON bar WITH ROWID;
CREATE MATERIALIZED VIEW foo_bar
NOLOGGING
CACHE
BUILD IMMEDIATE
REFRESH FAST ON COMMIT AS SELECT foo.foo,
bar.bar,
foo.ROWID AS foo_rowid,
bar.ROWID AS bar_rowid
FROM foo, bar
WHERE foo.foo = bar.foo;
L'avez-vous essayé sans rejoindre la norme ANSI?
CREATE MATERIALIZED VIEW MV_Test
NOLOGGING
CACHE
BUILD IMMEDIATE
REFRESH FAST ON COMMIT
AS
SELECT V.*, P.* FROM TPM_PROJECTVERSION V,TPM_PROJECT P
WHERE P.PROJECTID = V.PROJECTID
Vous obtiendrez l'erreur sur REFRESH_FAST si vous ne créez pas de journaux de vues matérialisées pour la ou les tables principales auxquelles la requête fait référence. Si quelqu'un ne connaît pas bien les vues matérialisées ou ne les utilise pas pour la première fois, le meilleur moyen consiste à utiliser Oracle sqldeveloper et à insérer graphiquement les options. Les erreurs fournissent également un sens bien meilleur.
La vérification des clés pour FAST REFRESH comprend les éléments suivants:
1) An Oracle materialized view log must be present for each base table.
2) The RowIDs of all the base tables must appear in the SELECT list of the MVIEW query definition.
3) If there are outer joins, unique constraints must be placed on the join columns of the inner table.
No 3 est facile à manquer et mérite d'être souligné ici