Search code examples
oracleoracle10goracle-xe

Materialized view data doesn't update


I want to create a materialized view with fast refresh. The view aggregates values from a single table:

CREATE TABLE N_INSP_DTSEDIF_PLANTAS (
    IMPORTACION_ID NUMBER(*,0) NOT NULL,
    ID NUMBER(10) NOT NULL,
    INSPECCION_ID NUMBER(10) NOT NULL,
    NOMBRE_PLANTA VARCHAR2(255 CHAR),
    NUM_VIVIENDAS NUMBER(10),
    SUP_CONSTRUIDA_VIVIENDAS DECIMAL(10,4),
    -- Plus some other columns I don't need    
    CONSTRAINT N_INSP_DTSEDIF_PLANTAS_P PRIMARY KEY (
        IMPORTACION_ID,
        ID
    ) ENABLE,

    CONSTRAINT N_INSP_DTSEDIF_PLANTAS_F FOREIGN KEY (IMPORTACION_ID)
        REFERENCES IMPORTACION (IMPORTACION_ID)
        ON DELETE CASCADE
        ENABLE
);

CREATE INDEX N_INSP_DTSEDIF_PLANTAS_X ON N_INSP_DTSEDIF_PLANTAS (IMPORTACION_ID);

CREATE SEQUENCE N_INSP_DTSEDIF_PLANTAS_S
INCREMENT BY 1
START WITH 1
MINVALUE 1
CACHE 20;

CREATE OR REPLACE TRIGGER N_INSP_DTSEDIF_PLANTAS_T
    BEFORE INSERT
    ON N_INSP_DTSEDIF_PLANTAS
    REFERENCING NEW AS NEW OLD AS OLD
    FOR EACH ROW
BEGIN
    IF :NEW.ID IS NULL THEN
        SELECT N_INSP_DTSEDIF_PLANTAS_S.NEXTVAL INTO :NEW.ID FROM DUAL;
    END IF;
END N_INSP_DTSEDIF_PLANTAS_T;
/
ALTER TRIGGER N_INSP_DTSEDIF_PLANTAS_T ENABLE;

I've composed this through trial and error:

CREATE MATERIALIZED VIEW LOG ON N_INSP_DTSEDIF_PLANTAS
WITH ROWID, SEQUENCE (IMPORTACION_ID, INSPECCION_ID, NUM_VIVIENDAS, SUP_CONSTRUIDA_VIVIENDAS)
INCLUDING NEW VALUES;

CREATE MATERIALIZED VIEW V_PLANTAS
REFRESH FAST
AS
SELECT IMPORTACION_ID, INSPECCION_ID,
SUM(NUM_VIVIENDAS) AS NUM_VIVIENDAS, SUM(SUP_CONSTRUIDA_VIVIENDAS) AS SUP_CONSTRUIDA_VIVIENDAS
FROM N_INSP_DTSEDIF_PLANTAS
GROUP BY IMPORTACION_ID, INSPECCION_ID;

Objects get created without errors and SELECT * FROM V_PLANTAS returns data. However, the view is stalled. New rows added to N_INSP_DTSEDIF_PLANTAS don't show up at V_PLANTAS.

What did I misunderstand from the documentation?


Solution

  • In the mess of random changes that follow panic and despair I inadvertently dropped the ON COMMIT clause:

    CREATE MATERIALIZED VIEW V_PLANTAS
    REFRESH FAST ON COMMIT
    AS
    -- ...
    

    The log itself is also invalid for fast refresh because I also omitted the PRIMARY KEY clause. It should be like:

    CREATE MATERIALIZED VIEW LOG ON N_INSP_DTSEDIF_PLANTAS
    WITH ROWID, PRIMARY KEY, SEQUENCE (INSPECCION_ID, NUM_VIVIENDAS, SUP_CONSTRUIDA_VIVIENDAS)
    INCLUDING NEW VALUES;
    

    (Said that, it's worth noting that materialized tables are not just a simple results cache but a fairly large and complex feature that requires careful planning and maintenance. In many situations is easier to just optimize the underlying query.)