Bonjour,

J'ai deux requêtes différentes, qui sélectionnent la même colonne d'une même table de type NUMBER(6,0).

Pourtant, lorsque je parse les deux requêtes, dbms_sql.describe_columns2 me renvoie bien NUMBER(6,0) pour la première, mais NUMBER(0, -127) pour la seconde !?!?

Je savais que dbms_sql.describe_columns était buggée, mais j'ignorais que dbms_sql.describe_columns2 l'était également...

Si quelqu'un voit une solution...

Voici le script permettant de reproduire le bug :

Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
 
SET serveroutput ON;
 
CREATE TABLE test1(col_number_6 NUMBER(6), col_id_test2 NUMBER(6));
 
CREATE TABLE test2(col_id_test2 NUMBER(6));
 
declare
  curseur number;     /* Pointeur sur le Curseur Dynamique  */
  result number;      /* Resultat sur l'ordre de la requete (OK/KO) */
  nbr_col integer;    /* Nbre de colonne de la requete      */
  les_colonnes dbms_sql.desc_tab2;  /* Structure donnant le descriptif des colonnes */
 
 
  procedure decrit_la_colonne(rec IN dbms_sql.desc_rec2) IS
  begin
    dbms_output.put_line('-----------------------------------------------------------');
    dbms_output.put_line('col_type            =    ' || rec.col_type);
    dbms_output.put_line('col_maxlen          =    ' || rec.col_max_len);
    dbms_output.put_line('col_name            =    ' || rec.col_name);
    dbms_output.put_line('col_name_len        =    ' || rec.col_name_len);
    dbms_output.put_line('col_schema_name     =    ' || rec.col_schema_name);
    dbms_output.put_line('col_schema_name_len =    ' || rec.col_schema_name_len);
    dbms_output.put_line('col_precision       =    ' || rec.col_precision);
    dbms_output.put_line('col_scale           =    ' || rec.col_scale);
    dbms_output.put('col_null_ok         =    ');
 
    IF (rec.col_null_ok) Then
           dbms_output.put_line('Oui'); 
    else    
           dbms_output.put_line('Non'); 
    end IF;
  end;
 
begin
  curseur := dbms_sql.open_cursor;
  dbms_sql.parse(curseur, 'select col_number_6 from test1', dbms_sql.native);
  result := dbms_sql.execute(curseur);
  dbms_sql.describe_columns2(curseur, nbr_col, les_colonnes);
 
  ----------------------------------------------------------------
  --   Je decrit les colonnes de ma requete
  ----------------------------------------------------------------
  FOR j IN 1..nbr_col Loop
      decrit_la_colonne(les_colonnes(j));
  End Loop;
 
  dbms_sql.close_cursor(curseur);
 
  curseur := dbms_sql.open_cursor;
  dbms_sql.parse(curseur, 'select col_number_6 from (test1 FULL OUTER JOIN test2 ON test1.col_id_test2 = test2.col_id_test2)', dbms_sql.native);
  result := dbms_sql.execute(curseur);
  dbms_sql.describe_columns2(curseur, nbr_col, les_colonnes);
 
  ----------------------------------------------------------------
  --   Je decrit les colonnes de ma requete
  ----------------------------------------------------------------
  FOR j IN 1..nbr_col Loop
      decrit_la_colonne(les_colonnes(j));
  End Loop;
 
  dbms_sql.close_cursor(curseur);
 
end;
/
Et le résultat, correct pour la première requête, totalement faux pour la seconde... :

Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
-----------------------------------------------------------
col_type            =    2
col_maxlen          =    22
col_name            =    COL_NUMBER_6
col_name_len        =    12
col_schema_name     =
col_schema_name_len =    0
col_precision       =    6
col_scale           =    0
col_null_ok         =    Oui
-----------------------------------------------------------
col_type            =    2
col_maxlen          =    22
col_name            =    COL_NUMBER_6
col_name_len        =    12
col_schema_name     =
col_schema_name_len =    0
col_precision       =    0
col_scale           =    -127
col_null_ok         =    Oui

PL/SQL procedure successfully completed.