2011-09-21 24 views
32

Así que estoy bastante seguro de que Oracle admite esto, así que no tengo idea de lo que estoy haciendo mal. Este código funciona:Oracle: cómo crear una vista materializada con FAST REFRESH y se une a

CREATE MATERIALIZED VIEW MV_Test 
    NOLOGGING 
    CACHE 
    BUILD IMMEDIATE 
    REFRESH FAST ON COMMIT 
    AS 
    SELECT V.* FROM TPM_PROJECTVERSION V; 

Si agrego en una unión, se rompe:

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 

Ahora me sale el error:

ORA-12054: no se puede establecer ON COMMIT atributo de actualización para la vista materializada

He creado registros de vistas materializadas tanto en TPM_PROJECT como en TPM_PROJECTVERSION. TPM_PROJECT tiene una clave principal de PROJECTID y TPM_PROJECTVERSION tiene una clave primaria compuesta de (PROJECTID, VERSIONID). ¿Cuál es el truco para esto? He estado buscando en los manuales de Oracle en vano. ¡Gracias!

+2

¿Usted intentó 'DBMS_MVIEW.EXPLAIN_MVIEW'? Debería mostrarle las opciones disponibles para la vista? – a1ex07

+0

Lo primero que haría es perder el * en la cláusula de selección. No estoy seguro de cómo manejaría la vista los nombres de columnas duplicados – Phil

+0

Sí, he estado tratando de averiguar cómo ejecutar DBMS_MVIEW.EXPLAIN_MVIEW pero todavía no lo he conseguido: lo siento, soy muy nuevo en Oracle. –

Respuesta

42

Para empezar, desde el Oracle Database Data Warehousing Guide:

Restrictions on Fast Refresh on Materialized Views with Joins Only

...

  • Rowids of all the tables in the FROM list must appear in the SELECT list of the query.

Esto significa que su estado de cuenta tendrá que ser algo como esto:

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 

Otro aspecto clave a tener en cuenta es que su los registros de vista materializados se deben crear como with rowid.

A continuación se muestra un escenario de prueba funcional:

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; 
+2

Uggghhhh mierda santa gracias! Eso FINALMENTE funcionó. Realmente no entiendo el punto de vista materializada en Oracle. Están limitados al punto en que no son realmente útiles para nadie.Me pregunto si las vistas indizadas en MS SQL son mejores. –

+1

Las vistas indizadas en MS SQL son diferentes, siempre se actualizan de inmediato, pero existen algunas limitaciones bastante severas, como no tener subconsultas, sin uniones externas, sin vistas indexadas anidadas, sin funciones no deterministas, etc. Consulte https://docs.microsoft.com/en-us/sql/relational-databases/views/create-indexed-views – DaveBoltman

5

¿Lo ha intentado sin la unión 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 
+1

Hmm esto parece funcionar mágicamente mejor. Sin embargo, ahora recibo un error sobre REFRESH FAST. Si lo cambio a REFRESH COMPLETE, crea la vista. Esto podría generar algunas actualizaciones muy lentas si tiene que ejecutar manualmente toda esa consulta cada vez que se actualicen las tablas subyacentes. Pensé que REFERIR RÁPIDO estaba permitido siempre que hubiera registros de vista materializados para cada tabla. –

+0

De hecho, hace algún tiempo creé un caso para eso en Oracle. Oracle considera esto solo como una "falta de documentación" ¡no como un error! Por lo tanto, la antigua sintaxis de Oracle aún es necesaria. –

3

Usted recibirá el error en REFRESH_FAST, si no se crea materializado ver los registros de la tabla (s) maestro de la consulta se refería. Si alguien no está familiarizado con las vistas materializadas o lo usa por primera vez, la mejor manera es usar Oracle sqldeveloper y poner gráficamente las opciones, y los errores también proporcionan mucho mejor sentido.

1

Los controles clave para rápida actualización incluye lo siguiente:

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. 

n 3 es fácil pasar por alto y vale la pena destacar aquí

Cuestiones relacionadas