Introduction
Sur Oracle 11gR2 (et peut-être sur les versions précédentes), il existe un bug très curieux : les vues du dictionnaire de données comme DICT ne sont pas accessibles une fois la base ouverte si on a fait un DESC sur ces vues avant que la base ne soit ouverte. En d'autre mots, si on ouvre la base de données étape par étape (STARTUP NOMOUNT puis des ALTER DATABASE) et qu'on veuille accéder à ces vues à une étape où elles ne sont pas encore accessibles, alors elles restent inaccessibles même quand la base est OPEN!

Nous allons prendre comme exemple la vue DICT mais cela concerne aussi les autres vues du dictionnaire de données comme DBA_TABLES.




Points d'attention
NA.



Base de tests
Une base 11g.



Exemples
============================================================================================
Le bug avec Oracle 11g
============================================================================================
On se connecte à une instance Oracle 11g arrêtée, on la démarre étape par étape et on exécute un DESC sur DICT à chaque étape. Quel intérêt me direz-vous puisque cette vue n'est connue que si la base est ouverte? Oui mais quand j'étais DBA junior je ne connaissais pas cette règle et donc en voulant savoir quelles vues étaient accessibles lors des phases du STARTUP, je faisais un DESC DICT lors de chaque phase, ne connaissant pas V$FIXED_TABLE ou V$FIXED_VIEW_DEFINITION mais que DICT et c'est comme ça que j'ai découvert ce bug.

On se connecte à une base fermée.
          SQL> connect / as sysdba
          Connected to an idle instance.
     
          SQL> startup nomount
          ORACLE instance started.
     
La vue DICT n'est pas connue à l'étape NOMOUNT, c'est normal, la base n'est pas ouverte et DICT fait partie du dictionnaire de données de la base.
         
SQL> desc dict;
          ERROR:
          ORA-04043: object dict does not exist

On monte la base : même message d'erreur; à nouveau c'est normal car la base n'est pas ouverte.
          SQL> alter database mount;
          Database altered.
     
          SQL> desc dict;
          ERROR:
          ORA-04043: object dict does not exist

On ouvre la base et, normalement, le DESC devrait fonctionner mais non! Oracle 11g nous retourne le même message d'erreur que précédemment.
          SQL> alter database open;
          Database altered.
   
          SQL> desc dict;
          ERROR:
          ORA-04043: object dict does not exist

Pour prouver que ma base est OK, je fais un shutdown puis un startup simple --> DICT est bien connue. Cela signifie que c'est la séquence des ordres SQL*Plus et SQL que j'aie exécutée qui provoque cette erreur. Pour rappel, DESC et STARTUP sont des ordres SQL*Plus mais ALTER DATABASE est un ordre SQL.
          SQL> shutdown immediate
          Database closed.
          Database dismounted.
          ORACLE instance shut down.
     
          SQL> startup
          ORACLE instance started.
     
          SQL> desc dict;
          Name                                      Null?    Type
          ----------------------------------------- -------- ----------------------------
          TABLE_NAME                                         VARCHAR2(30)
          COMMENTS                                           VARCHAR2(4000)


Sur le forum developpez.com, l'internaute Baldrick a donné la solution à ce problème : il faut faire un ALTER SYSTEM FLUSH SHARED_POOL pour que le DESC DICT refonctionne quand la base est OPEN et qu'Oracle reconnaisse l'objet.

L'explication est la suivante : soit Oracle met un indicateur sur l'objet comme étant inconnu et interdit toute opération dessus, même avec la base OPEN, soit il conserve dans la SHARED POOL le résultat des commandes DESC passées avant l'étape OPEN et ressort le même résultat après l'ouverture de la base, sans réexécuter le DESC pour gagner du temps. N'ayant plus de base 11g à disposition, je ne peux pas faire de nouveaux tests mais dans mon souvenir, même un SELECT COUNT(*) FROM DICT provoquait une erreur. Cela me porte à penser qu'Oracle flag l'objet comme étant inconnu, même si la base devient OPEN plutôt que de renvoyer le résultat d'un ordre SQL*Plus.

============================================================================================
Comportement OK avec une base Oracle 12c en architecture multi-tenant
============================================================================================

A noter que ce bug a été corrigé en 12c comme on va le voir, du moins sur une base avec la nouvelle architecture multi-tenant. Il faut dire aussi qu'avec l'introduction de celle-ci tellement de choses ont été réécrites...
          [oracle@vbgeneric ~]$ sqlplus SYS/oracle@orcl12c as sysdba
          Connected to an idle instance.

          SQL> startup nomount
          ORACLE instance started.

          SQL> show con_name
          CON_NAME
          ------------------------------
          CDB$ROOT

          SQL> desc dict
          ERROR:
          ORA-04043: object dict does not exist

          SQL> alter database mount;
          Database altered.

          SQL> desc dict
          ERROR:
          ORA-04043: object dict does not exist

Maintenant c'est OK, le bug a été corrigé!
          SQL> alter database open;
          Database altered.

          SQL> desc dict
          Name                       Null?      Type
          ----------------------------------------- -------- ----------------------------
          TABLE_NAME                        VARCHAR2(128)
          COMMENTS                          VARCHAR2(4000)