web-dev-qa-db-fra.com

Oracle - Comment créer une vue matérialisée avec FAST REFRESH et JOINS

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!

35
Mike Christensen

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;
45
Allan

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
5
steve godfrey

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.

3
Paul

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

1
pahariayogi