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

Oracle Discussion :

Conversion en numérique d'un ID : erreur nombre non valide


Sujet :

Oracle

  1. #1
    Membre expert
    Avatar de Alexandre T
    Homme Profil pro
    Chef de projets AMO
    Inscrit en
    Mai 2002
    Messages
    1 213
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 47
    Localisation : France, Gironde (Aquitaine)

    Informations professionnelles :
    Activité : Chef de projets AMO
    Secteur : Transports

    Informations forums :
    Inscription : Mai 2002
    Messages : 1 213
    Points : 3 001
    Points
    3 001
    Par défaut Conversion en numérique d'un ID : erreur nombre non valide
    Bonjour,

    Je travaille sur une base de production très mal montée. Les merisiens ou autres adeptes de bases bien propres en seraient médusés. Mais je dois faire avec, je n'ai pas le choix.

    Sur la base de développement je lance (en simplifiant la requête):
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
     
    SELECT max(TO_NUMBER(msgid)) as msgid_max
      FROM messages
     WHERE TO_NUMBER(msgid) >= 10 AND TO_NUMBER(msgid) < 50
    Cela marche très bien. Mais je vois venir la question sur la nature de colonne alors j'y réponds de suite : Oui les messages sont stockés en chaine de caractère, je sais c'est nul, mais que voulez-vous...

    Malheureusement en production, et bien j'ai des chaines de caractères du genre 'TOTO'... Du coup je ne peux pas les convertir en string. Ce même script retourne la fatidique erreur :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    Erreur nombre non valide
    Ma question, comment faire pour lui dire que si msgid n'est pas un nombre alors la valeur est zéro ?
    Alexandre Tranchant
    Chef de projet AMO pour le Cerema.
    Retrouvez mes articles sur PHP et Symfony

  2. #2
    Membre expert

    Homme Profil pro
    Chef de projet en SSII
    Inscrit en
    Janvier 2004
    Messages
    2 862
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Loire Atlantique (Pays de la Loire)

    Informations professionnelles :
    Activité : Chef de projet en SSII
    Secteur : Conseil

    Informations forums :
    Inscription : Janvier 2004
    Messages : 2 862
    Points : 3 609
    Points
    3 609
    Par défaut
    Tu peux creer une fonction IS_NUMBER
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    create or replace function is_number (msg_id in varchar2) 
    return number is
    begin
       v_num := to_number (msg_id);
       return (1);
    exception
       when others then return (0);
    end;
    /
    Et tu adaptes ta requête de la manière suivante :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    select max (decode (is_number(msg_id), 1, to_number(msg_id), 0))
    from messages
    where ...
    Une autre solution peut-être un fonction qui te renvoie soit msg_id, soit 0 dans le même principe que celle proposée.
    Un problème sans solution est un problème mal posé

    Merci de poser vos questions sur le forum, je ne réponds pas aux questions posées par MP.

  3. #3
    Membre averti

    Inscrit en
    Septembre 2003
    Messages
    425
    Détails du profil
    Informations forums :
    Inscription : Septembre 2003
    Messages : 425
    Points : 398
    Points
    398
    Par défaut
    Nous avons réglé ca via PL nous :
    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
     
    function f_ret_numeric(xvar_num in varchar2) return number
       as
       --------------------------------------------------------------------------
       -- But   : retourne un nombre sinon 0 si c'est pas un nombre
       -- Param : xvar_num     IN : chaine à tester
       --         return : 0 si ce N'est PAS un nombre
       --                  le nombre si c'est un nombre
       --------------------------------------------------------------------------
          wnumber     number;
       begin
          wnumber := to_number(xvar_num);
          return wnumber ;
       exception
          when others then
             return 0;
       end;
    Ah la normalisation c'est pas si mal qd meêm bon courage à toi en tout cas !

  4. #4
    Membre expert
    Avatar de Alexandre T
    Homme Profil pro
    Chef de projets AMO
    Inscrit en
    Mai 2002
    Messages
    1 213
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 47
    Localisation : France, Gironde (Aquitaine)

    Informations professionnelles :
    Activité : Chef de projets AMO
    Secteur : Transports

    Informations forums :
    Inscription : Mai 2002
    Messages : 1 213
    Points : 3 001
    Points
    3 001
    Par défaut
    Oui.... Mais je n'ai pas le droit d'utiliser le PL ... Je sais c'est pénible, mais que voulez-vous... Bon je vais essayer une astuce à deux francs si sous... avec des REPLACE pour remplacer toutes les valeurs qui ne sont pas des chiffres par des zéros...
    Alexandre Tranchant
    Chef de projet AMO pour le Cerema.
    Retrouvez mes articles sur PHP et Symfony

  5. #5
    Membre expert
    Avatar de LeoAnderson
    Profil pro
    Inscrit en
    Septembre 2004
    Messages
    2 938
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Septembre 2004
    Messages : 2 938
    Points : 3 199
    Points
    3 199
    Par défaut
    Voilà, la solution c'est ça !

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
     Where LENGTH (TRIM (TRANSLATE ( MsgID,  ' +-.0123456789',' ') ) ) IS NULL
    IS NULL <=> numérique

  6. #6
    Membre expert
    Avatar de Alexandre T
    Homme Profil pro
    Chef de projets AMO
    Inscrit en
    Mai 2002
    Messages
    1 213
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 47
    Localisation : France, Gironde (Aquitaine)

    Informations professionnelles :
    Activité : Chef de projets AMO
    Secteur : Transports

    Informations forums :
    Inscription : Mai 2002
    Messages : 1 213
    Points : 3 001
    Points
    3 001
    Par défaut
    J'avais un problème de connexion, j'ai juste pu noté résolu Mais pas pu poster mon message de remerciement Merci
    Alexandre Tranchant
    Chef de projet AMO pour le Cerema.
    Retrouvez mes articles sur PHP et Symfony

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

    Informations forums :
    Inscription : Janvier 2004
    Messages : 15 967
    Points : 19 073
    Points
    19 073
    Par défaut
    on aurait aussi pu passer par une table temporaire ou un trigger mais bon

  8. #8
    Membre chevronné

    Profil pro
    Inscrit en
    Avril 2005
    Messages
    1 673
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Avril 2005
    Messages : 1 673
    Points : 1 775
    Points
    1 775
    Par défaut
    Citation Envoyé par LeoAnderson
    Voilà, la solution c'est ça !

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
     Where LENGTH (TRIM (TRANSLATE ( MsgID,  ' +-.0123456789',' ') ) ) IS NULL
    IS NULL <=> numérique
    En faisant une recherche avancée je suis tombé sur ce post et cette solution ne me semble pas correcte :
    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
    8i CYRIL> SELECT '1'
      2  FROM DUAL
      3  WHERE LENGTH (TRIM (TRANSLATE ( '-12.0345',  ' +-.0123456789',' ') ) ) IS NULL;
     
    '
    -
    1
     
    1 ligne sélectionnée.
     
    8i CYRIL> SELECT '1'
      2  FROM DUAL
      3  WHERE LENGTH (TRIM (TRANSLATE ( 'this is a text',  ' +-.0123456789',' ') ) ) IS NULL;
     
    aucune ligne sélectionnée
     
    8i CYRIL> SELECT '1'
      2  FROM DUAL
      3  WHERE LENGTH (TRIM (TRANSLATE ( '-12.-12',  ' +-.0123456789',' ') ) ) IS NULL;
     
    '
    -
    1
     
    1 ligne sélectionnée.
    Eh oui la dernière instruction indique que la chaîne "-12.-12" correspond effectivement à un nombre valide, ce qui n'est pas le cas

    La raison de cet échec est que le nombre de séparateur de décimales, de signes négatif, etc. est décisif dans la détermination du fait que la variable de caractères passée en paramètre est un nombre ou non.

    Vous me corrigerez si je me trompe.
    Modérateur des forums Oracle et Langage SQL
    Forum SQL : je n'interviens PAS plus de 4 fois dans une discussion car si c'est nécessaire cela prouve généralement que vous n'avez pas respecté : les règles du forum

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. Erreur 'Nombre non valide'
    Par Touty11 dans le forum SQL
    Réponses: 4
    Dernier message: 25/03/2012, 18h07
  2. ORA-01722: Nombre non valide
    Par misa dans le forum Oracle
    Réponses: 4
    Dernier message: 18/12/2007, 15h23
  3. Réponses: 7
    Dernier message: 03/05/2007, 12h44
  4. Réponses: 8
    Dernier message: 08/09/2006, 14h09
  5. erreur: usage non valide du null
    Par Pau dans le forum Access
    Réponses: 2
    Dernier message: 28/04/2006, 10h41

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