ORA-12899: value too large for column lors du rafraîchissement d’une vue matérialisée

La longueur des colonnes d’une vue matérialisée est définie lors de la création de la vue matérialisée. Si la longueur d’une colonne d’une table utilisée dans la vue matérialisée change, la taille de la colonne correspondante dans la vue matérialisée n’est pas modifiée ce qui peut conduire à une erreur ORA-12899 si la longueur a été augmentée.

Exemple :

SQL> create table t(x varchar2(4));

Table T created.

SQL> create materialized view mv as select * from t;

Materialized view MV created.

SQL> desc mv
Name Null? Type 
---- ----- ----------- 
X          VARCHAR2(4) 

SQL> select object_name,object_type,status from user_objects where object_name = 'MV';

OBJECT_NAME     OBJECT_TYPE             STATUS 
--------------- ----------------------- -------
MV              TABLE                   VALID 
MV              MATERIALIZED VIEW       VALID

SQL> select mview_name,staleness,compile_state from user_mviews where mview_name = 'MV';

MVIEW_NAME      STALENESS           COMPILE_STATE 
--------------- ------------------- -------------------
MV              FRESH               VALID

SQL> alter table t modify x varchar2(8);

Table T altered.

SQL> desc mv
Name Null? Type 
---- ----- ----------- 
X VARCHAR2(4) 

SQL> select object_name,object_type,status from user_objects where object_name = 'MV';

OBJECT_NAME     OBJECT_TYPE             STATUS 
--------------- ----------------------- -------
MV              TABLE                   VALID 
MV              MATERIALIZED VIEW       INVALID

SQL> select mview_name,staleness,compile_state from user_mviews where mview_name = 'MV';

MVIEW_NAME      STALENESS           COMPILE_STATE 
--------------- ------------------- -------------------
MV              NEEDS_COMPILE       NEEDS_COMPILE

SQL> insert into t(x) values ('Olivier');

1 row inserted.

SQL> commit;

Commit complete.

SQL> exec dbms_mview.refresh('mv')

Error starting at line : 1 in command -
BEGIN dbms_mview.refresh('mv'); END;
Error report -
ORA-12008: error in materialized view refresh path
ORA-12899: value too large for column "OHEURTEL"."MV"."X" (actual: 7, maximum: 4)
ORA-06512: at "SYS.DBMS_SNAPSHOT", line 2821
ORA-06512: at "SYS.DBMS_SNAPSHOT", line 3058
ORA-06512: at "SYS.DBMS_SNAPSHOT", line 3017
ORA-06512: at line 1

SQL> desc mv
Name Null? Type 
---- ----- ----------- 
X          VARCHAR2(4) 

SQL> select object_name,object_type,status from user_objects where object_name = 'MV';

OBJECT_NAME     OBJECT_TYPE             STATUS 
--------------- ----------------------- -------
MV              TABLE                   VALID 
MV              MATERIALIZED VIEW       INVALID

SQL> select mview_name,staleness,compile_state from user_mviews where mview_name = 'MV';

MVIEW_NAME      STALENESS           COMPILE_STATE 
--------------- ------------------- -------------------
MV              COMPILATION_ERROR   COMPILATION_ERROR 

Comme le montre cet exemple, après avoir augmenté la longueur d’une colonne de la table sous-jacente, la vue matérialisée a été marquée INVALID et  NEEDS_COMPILE (à recompiler). Lors du rafraîchissement de la vue matérialisée, Oracle a tenté de recompiler la vue mais sans succès ; la longueur de la colonne dans la vue matérialisée est restée inchangée ce qui a provoqué l’erreur ORA-12899.

Pour résoudre ce problème, le plus simple, sans reconstruire complètement la vue matérialisée, consiste à modifier aussi la longueur de la colonne dans la vue matérialisée.

Exemple : 

SQL> alter materialized view mv modify x varchar2(8);

Materialized view MV altered.

SQL> exec dbms_mview.refresh('mv')

PL/SQL procedure successfully completed.

SQL> desc mv
Name Null? Type        
---- ----- ----------- 
X          VARCHAR2(8) 

SQL> select object_name,object_type,status from user_objects where object_name = 'MV';

OBJECT_NAME     OBJECT_TYPE             STATUS 
--------------- ----------------------- -------
MV              TABLE                   VALID  
MV              MATERIALIZED VIEW       VALID  

SQL> select mview_name,staleness,compile_state from user_mviews where mview_name = 'MV';

MVIEW_NAME      STALENESS           COMPILE_STATE      
--------------- ------------------- -------------------
MV              FRESH               VALID              

Laisser un commentaire