IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

SQL Oracle Discussion :

[9i] bug dbms_sql.describe_columns2


Sujet :

SQL Oracle

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre confirmé
    Inscrit en
    Janvier 2006
    Messages
    120
    Détails du profil
    Informations forums :
    Inscription : Janvier 2006
    Messages : 120
    Par défaut [9i] bug dbms_sql.describe_columns2
    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.

  2. #2
    Rédacteur

    Homme Profil pro
    Développeur et DBA Oracle
    Inscrit en
    Octobre 2006
    Messages
    878
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Algérie

    Informations professionnelles :
    Activité : Développeur et DBA Oracle

    Informations forums :
    Inscription : Octobre 2006
    Messages : 878
    Par défaut
    salut,

    j'ai remplacé le FULL OUTER JOIN par un union all est ca marche.

    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
     
    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 test1.col_number_6 
                                             from test1 , test2 
                                              where  test1.col_id_test2(+) = test2.col_id_test2
                                        union all 
                                        select test1.col_number_6 
                                        from test1 , test2 
                                            where  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;
    /
    Le résultat
    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
     
    SQL> /
    -----------------------------------------------------------
    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       =    6
    col_scale           =    0
    col_null_ok         =    Oui
     
    Procédure PL/SQL terminée avec succès.

  3. #3
    Membre confirmé
    Inscrit en
    Janvier 2006
    Messages
    120
    Détails du profil
    Informations forums :
    Inscription : Janvier 2006
    Messages : 120
    Par défaut
    Merci mais le problème est que ce morceau de code fait partie d'une plus grosse requête (j'ai simplement isolé le problème), mais dans le cadre de ma requête originale, le FULL OUTER JOIN est OBLIGATOIRE... Ce sont en fait des requêtes programmées par des utilisateurs avancés, et je me vois mal leur expliquer qu'il leur est interdit de faire des FULL OUTER JOIN, et qu'il leur faut réécrire leurs requêtes de façon beaucoup plus complexe...

    De plus, il n'est tout de même pas normal que ça bugge, que ce soit un FULL OUTER JOIN ou un UNION ALL : ça devrait marcher dans les 2 cas... Je me trompe?

    Merci,

    Nico'

  4. #4
    Expert éminent
    Avatar de orafrance
    Profil pro
    Inscrit en
    Janvier 2004
    Messages
    15 967
    Détails du profil
    Informations personnelles :
    Âge : 48
    Localisation : France

    Informations forums :
    Inscription : Janvier 2004
    Messages : 15 967
    Par défaut
    FOJ et UNION ALL ça fait pas du tout la même chose alors vérifie quand même que ta requête est correcte... le bug serait plutôt dans celle-ci

  5. #5
    Membre confirmé
    Inscrit en
    Janvier 2006
    Messages
    120
    Détails du profil
    Informations forums :
    Inscription : Janvier 2006
    Messages : 120
    Par défaut
    Citation Envoyé par orafrance
    FOJ et UNION ALL ça fait pas du tout la même chose alors vérifie quand même que ta requête est correcte... le bug serait plutôt dans celle-ci

    En fait, ma requête d'origine (avec le FULL OUTER JOIN) produit bien le résultat escompté par les utilisateurs.

    Le problème est qu'en la parsant avec dbms_sql.describe_columns2, la colonne retournée est d'un type aberrant!!! Même si la requête produit un résultat mauvais fonctionnellement, ce n'est pas une raison valable pour qu'un NUMBER(6, 0) se tranforme en NUMBER(0, -127) !?!?!

  6. #6
    Expert éminent
    Avatar de orafrance
    Profil pro
    Inscrit en
    Janvier 2004
    Messages
    15 967
    Détails du profil
    Informations personnelles :
    Âge : 48
    Localisation : France

    Informations forums :
    Inscription : Janvier 2004
    Messages : 15 967
    Par défaut
    Citation Envoyé par Nico57
    ce n'est pas une raison valable pour qu'un NUMBER(6, 0) se tranforme en NUMBER(0, -127) !?!?!
    Ca me parait être une valeur qui pourrait correspondre à une colonne NULL

  7. #7
    Rédacteur

    Homme Profil pro
    Développeur et DBA Oracle
    Inscrit en
    Octobre 2006
    Messages
    878
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Algérie

    Informations professionnelles :
    Activité : Développeur et DBA Oracle

    Informations forums :
    Inscription : Octobre 2006
    Messages : 878
    Par défaut
    Salut ,

    C'est pas moi qu'il a inventé mais tu peux lire cette article (Full Outer Join)
    http://www.oreillynet.com/pub/a/netw.../fulljoin.html

Discussions similaires

  1. Réponses: 2
    Dernier message: 06/03/2003, 16h37
  2. Bug new build ??
    Par rgarnier dans le forum XMLRAD
    Réponses: 4
    Dernier message: 31/01/2003, 10h30

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo