mardi 17 août 2010

SELECT FOR UPDATE OF et ORA-01733

En 11G R2, je suis tombé récemment sur un bug un peu "sioux" qui pourrait être simplifié par le testcase suivant:

SQL> create table t1 (t1_c1 number);

Table crÚÚe.

SQL> select x.t1_c1 from
2  (select t1.t1_c1 from t1) x
3  for update of x.t1_c1;
for update of x.t1_c1
*
ERREUR à la ligne 3 :
ORA-01733: les colonnes virtuelles ne sont pas autorisées ici


SQL> select b.t1_c1 from
2  (select t1.t1_c1 from t1) b
3  for update of b.t1_c1;

aucune ligne sélectionnée

En gros, lorsque j'alias ma subquery avec la lettre "X" j'obtiens une erreur ORA-01733, par contre si j'utilise une autre lettre ça fonctionne.

Bon, par rapport au progiciel sur lequel je travaille, le workaround est simple il suffit de modifier le nom de l'alias.

J'ai quand même ouvert un case au support Oracle pour en savoir plus, et apparemment cette erreur est dû au fait que j'ai dans ma base un fonction qui porte le nom "X".
En faisant, une petite recherche sur le nom de mes objets je me suis effectivement aperçu qu'il existait un synonyme public (pointant sur une fonction du schéma MDSYS) qui portait ce nom:

SQL> select SYNONYM_NAME,TABLE_OWNER,TABLE_NAME from all_synonyms where SYNONYM_NAME='X';

SYNONYM_NAME                   TABLE_OWNER                    TABLE_NAME
------------------------------ ----------------------------------------- 
X                              MDSYS                          OGC_X

Le schema MDSYS est généralement présent lorsque les options MULTIMEDIA ou SPATIAL ont été installées.
Si mon alias s'appelait TOTO et que j'avais une fonction ou un synonyme portant ce nom, je serais tombé sur la même erreur:
SQL> select toto.t1_c1 from
  2  (select t1.t1_c1 from t1) toto
  3  for update of toto.t1_c1;

aucune ligne sélectionnée

SQL> create or replace function toto return number is
  2  begin
  3     return 1;
  4  end;
  5  /

Fonction créée.

SQL> select toto.t1_c1 from
  2  (select t1.t1_c1 from t1) toto
  3  for update of toto.t1_c1;
for update of toto.t1_c1
              *
ERREUR à la ligne 3 :
ORA-01733: les colonnes virtuelles ne sont pas autorisées ici

 
Donc pour résumer, si un jour vous tombez sur cette erreur lors d'un SELECT FOR UPDATE OF c'est qu'il existe surement un objet dans votre base portant le même nom que l'alias de votre sous-requête.

1 commentaire: