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 :

Extraction de chaines numériques d'un VARCHAR


Sujet :

SQL Oracle

  1. #1
    Membre régulier
    Inscrit en
    Janvier 2005
    Messages
    104
    Détails du profil
    Informations forums :
    Inscription : Janvier 2005
    Messages : 104
    Points : 123
    Points
    123
    Par défaut Extraction de chaines numériques d'un VARCHAR
    Bonjour,

    Dans une procédure PL SQL, j'ai une variable de type VARCHAR qui ressemble à ça :

    "blabla 1234 blablabla 123 blabla 4567 blabla"

    Mon but est d'en extraire toutes les chaines numériques :
    1234
    123
    4567

    De façon à pouvoir faire une boucle sur ces chaines pour tester certaines propriétés.

    J'y parviens, mais avec une fonction très lourde et inélégante Existe-t-il une astuce pour le faire simplement ?

  2. #2
    McM
    McM est déconnecté
    Expert éminent

    Homme Profil pro
    Développeur Oracle
    Inscrit en
    Juillet 2003
    Messages
    4 580
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Développeur Oracle

    Informations forums :
    Inscription : Juillet 2003
    Messages : 4 580
    Points : 7 740
    Points
    7 740
    Billets dans le blog
    4
    Par défaut
    Y'a rien de prévu nativement.
    Comment tu boucles ?
    More Code : More Bugs. Less Code : Less Bugs
    Mon Blog PL/Sql : Fichier Zip / Image BMP / Lire sqliteDB / QRCode et Images PNG ou BMP

  3. #3
    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
    avec un translate ça devrait se faire facilement. Tu remplaces tout ce qui n'est pas un chiffre en espace et tu extraits les nombres avec des INSTR

  4. #4
    Membre confirmé Avatar de miloux32
    Profil pro
    Inscrit en
    Juillet 2003
    Messages
    545
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juillet 2003
    Messages : 545
    Points : 565
    Points
    565
    Par défaut
    Citation Envoyé par orafrance
    avec un translate ça devrait se faire facilement. Tu remplaces tout ce qui n'est pas un chiffre en espace et tu extraits les nombres avec des INSTR

    Tu peux meme faire mieux apres non ?
    genre en remplacant 2 espaces par un seul ( ainsi tu as une chaine "formatée")
    C'est pas parce que ca marche que c'est bon!!
    Pensez au bouton "Résolu"
    Je ne réponds pas en privé aux questions

  5. #5
    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
    Points : 1 197
    Points
    1 197
    Par défaut
    salut,

    Adaptes ce code à ton besoin.

    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
     
    CREATE OR REPLACE PACKAGE extraire_nb_pkg IS
    TYPE outrecset IS TABLE OF number;
    FUNCTION extraire_nb (v_chaine IN VARCHAR2)
    RETURN outrecset PIPELINED;
    END extraire_nb_pkg;
    --Package body 
    CREATE OR REPLACE PACKAGE BODY scott.extraire_nb_pkg
    IS
       FUNCTION extraire_nb (v_chaine IN VARCHAR2)
          RETURN outrecset PIPELINED
       IS
          v_number   NUMBER;
          i          NUMBER := 1;
       BEGIN
          LOOP
             SELECT REGEXP_SUBSTR (v_chaine, '[[:digit:]]+{1,10}', 1, i)
               INTO v_number
               FROM DUAL;
     
             PIPE ROW (v_number);
             EXIT WHEN v_number IS NULL AND i > 1;
             i := i + 1;
          END LOOP;
     
          RETURN;
       END;
    END extraire_nb_pkg;
    /
    Le résultat
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
     
    SQL> select * from table(extraire_nb_pkg.extraire_nb('blabla 1254 hdghjdgh 12546 hjggsdh 12547 sdvjs
     '));
     
    COLUMN_VALUE
    ------------
            1254
           12546
           12547

  6. #6
    Membre régulier
    Inscrit en
    Janvier 2005
    Messages
    104
    Détails du profil
    Informations forums :
    Inscription : Janvier 2005
    Messages : 104
    Points : 123
    Points
    123
    Par défaut
    Ca m'a l'air nickel cette fonction, mais je crois que REGEXP_SUBSTR ne fonctionne qu'à partir d'Oracle 10, ce sera dans quelques mois en ce qui me concerne En tout cas c'est bon à savoir.

    Sinon pour l'idée précédente, si j'ai bien compris il faut transormer

    "blabla 1234 blablabla 123 blabla 4567 blabla"

    en

    " 1234 123 4567 "

    Mais ensuite comment je fais pour boucler sur ces trois nombres ? (j'ai besoin pour chacun d'entre eux de tester leur valeur et selon les cas les mémoriser dans une variable). Je ne vois pas trop comment procéder avec des INSTR.

  7. #7
    McM
    McM est déconnecté
    Expert éminent

    Homme Profil pro
    Développeur Oracle
    Inscrit en
    Juillet 2003
    Messages
    4 580
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Développeur Oracle

    Informations forums :
    Inscription : Juillet 2003
    Messages : 4 580
    Points : 7 740
    Points
    7 740
    Billets dans le blog
    4
    Par défaut
    Citation Envoyé par orafrance
    avec un translate ça devrait se faire facilement. Tu remplaces tout ce qui n'est pas un chiffre en espace et tu extraits les nombres avec des INSTR
    C'est ce à quoi j'avais pensé mais si tu as ceci :
    "blabla 1234 blabla 5678 bla9bla"
    tu te retrouves avec "1234 5678 9"
    More Code : More Bugs. Less Code : Less Bugs
    Mon Blog PL/Sql : Fichier Zip / Image BMP / Lire sqliteDB / QRCode et Images PNG ou BMP

  8. #8
    McM
    McM est déconnecté
    Expert éminent

    Homme Profil pro
    Développeur Oracle
    Inscrit en
    Juillet 2003
    Messages
    4 580
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Développeur Oracle

    Informations forums :
    Inscription : Juillet 2003
    Messages : 4 580
    Points : 7 740
    Points
    7 740
    Billets dans le blog
    4
    Par défaut
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    WITH t AS (
      SELECT TRIM(TRANSLATE('blablabla 1234 blajafiojz 5678 bla9bla', ' ' || TRANSLATE('blablabla 1234 blajafiojz 5678 bla9bla', 'a 0123456789', 'a'), ' ')) AS c
    	FROM dual
       )
      SELECT DISTINCT extractvalue(COLUMN_VALUE,'/x')
      FROM t,
     TABLE(xmlsequence(EXTRACT(XMLTYPE('<list><x>'||REPLACE(c,' ','</x><x>')||'</x></list>'),
          '/list/x')))
    WHERE extractvalue(COLUMN_VALUE,'/x') IS NOT NULL
    More Code : More Bugs. Less Code : Less Bugs
    Mon Blog PL/Sql : Fichier Zip / Image BMP / Lire sqliteDB / QRCode et Images PNG ou BMP

  9. #9
    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
    Citation Envoyé par Tententai
    Mais ensuite comment je fais pour boucler sur ces trois nombres ? (j'ai besoin pour chacun d'entre eux de tester leur valeur et selon les cas les mémoriser dans une variable). Je ne vois pas trop comment procéder avec des INSTR.
    un truc du style :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
     
    chaine := LTRIM(TRANSLATE(UPPER(chaine),'ABCD...Z','    ... '));
    WHILE LENGTH(chaine)>0 LOOP
     chiffre := TO_NUMBER(RTRIM(SUBSTR(chaine,1,INSTR(LTRIM(chaine),' ')));
     chaine := LTRIM(SUBSTR(chaine,INSTR(LTRIM(chaine),' ')));
     dbms_output.put_line(chiffre);
    END LOOP;

  10. #10
    Membre régulier
    Inscrit en
    Janvier 2005
    Messages
    104
    Détails du profil
    Informations forums :
    Inscription : Janvier 2005
    Messages : 104
    Points : 123
    Points
    123
    Par défaut
    Ah ben pour la peine j'ai même plusieurs solutions

    En tests ça marche bien, je vais voir laquelle tourne le plus vite dans mon cas particulier.

    Merci à tous !

  11. #11
    McM
    McM est déconnecté
    Expert éminent

    Homme Profil pro
    Développeur Oracle
    Inscrit en
    Juillet 2003
    Messages
    4 580
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Développeur Oracle

    Informations forums :
    Inscription : Juillet 2003
    Messages : 4 580
    Points : 7 740
    Points
    7 740
    Billets dans le blog
    4
    Par défaut
    Attention avec la méthode d'orafrance tu peux avoir une boucle infinie !
    (Si la chaine se termine par un nombre)

    Rajoute toujours un espace à la fin de chaine
    More Code : More Bugs. Less Code : Less Bugs
    Mon Blog PL/Sql : Fichier Zip / Image BMP / Lire sqliteDB / QRCode et Images PNG ou BMP

  12. #12
    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
    bah non... je fais systématiquement un SUBSTR sur la chaine pour supprimer le nombre

  13. #13
    McM
    McM est déconnecté
    Expert éminent

    Homme Profil pro
    Développeur Oracle
    Inscrit en
    Juillet 2003
    Messages
    4 580
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Développeur Oracle

    Informations forums :
    Inscription : Juillet 2003
    Messages : 4 580
    Points : 7 740
    Points
    7 740
    Billets dans le blog
    4
    Par défaut
    Ben oui, mais le INSTR renvoie NULL s'il n'y a plus d'espaces

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    LTRIM(SUBSTR('8 ',INSTR(LTRIM('8 '),' '))) => NULL
    LTRIM(SUBSTR('8',INSTR(LTRIM('8'),' '))) => '8'
    En reprenant ton code (1 parenthèse de rajoutée)
    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
    DECLARE
    chaine VARCHAR2(20);
    chiffre NUMBER;
    i NUMBER := 0;
    BEGIN
    chaine := '123 456 8';
    WHILE LENGTH(chaine)>0 
    	AND i < 5
    LOOP
    	i := i + 1;
     chiffre := TO_NUMBER(RTRIM(SUBSTR(chaine,1,INSTR(LTRIM(chaine),' '))));
     chaine := LTRIM(SUBSTR(chaine,INSTR(LTRIM(chaine),' ')));
     DBMS_OUTPUT.PUT_LINE(chaine || ':= ' || chiffre);
    END LOOP;
    END;
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    456 8:= 123
    8:= 456
    8:= 
    8:= 
    8:= 
    (là ça boucle... ça s'arrête grâce à i)
    Avec chaine = '123 456 8 '
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    456 8 := 123
    8 := 456
    := 8
    More Code : More Bugs. Less Code : Less Bugs
    Mon Blog PL/Sql : Fichier Zip / Image BMP / Lire sqliteDB / QRCode et Images PNG ou BMP

  14. #14
    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
    ha oui... bien vu

    et ta solution est plus "classe"... même si je ne comprends rien

  15. #15
    McM
    McM est déconnecté
    Expert éminent

    Homme Profil pro
    Développeur Oracle
    Inscrit en
    Juillet 2003
    Messages
    4 580
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Développeur Oracle

    Informations forums :
    Inscription : Juillet 2003
    Messages : 4 580
    Points : 7 740
    Points
    7 740
    Billets dans le blog
    4
    Par défaut
    Elle vient pas de moi... j'ai jamais fait de XML.
    Pour rendre à César ce qui est à César, je vais rechercher le post pour savoir Qui avait posté ce truc
    More Code : More Bugs. Less Code : Less Bugs
    Mon Blog PL/Sql : Fichier Zip / Image BMP / Lire sqliteDB / QRCode et Images PNG ou BMP

  16. #16
    Membre régulier
    Inscrit en
    Janvier 2005
    Messages
    104
    Détails du profil
    Informations forums :
    Inscription : Janvier 2005
    Messages : 104
    Points : 123
    Points
    123
    Par défaut
    J'avoue que je suis aussi entrain d'essayer de comprendre comment ça marche (comme ça j'apprends le xml en même temps, hop)

  17. #17
    McM
    McM est déconnecté
    Expert éminent

    Homme Profil pro
    Développeur Oracle
    Inscrit en
    Juillet 2003
    Messages
    4 580
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Développeur Oracle

    Informations forums :
    Inscription : Juillet 2003
    Messages : 4 580
    Points : 7 740
    Points
    7 740
    Billets dans le blog
    4
    Par défaut
    Le problème d'origine était celui ci (j'ai pas retrouvé le post)

    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
    Découpage d'une chaine de caractère
     
    WITH t AS (
      SELECT 'Un, Trois, Cinq, Six' c FROM dual UNION ALL
      SELECT 'Un, Deux, Quatre' FROM dual UNION ALL
      SELECT 'Trois' FROM dual UNION ALL
      SELECT 'Sept, Huit' FROM dual UNION ALL
      SELECT 'Un, Six' FROM dual
       )
      SELECT DISTINCT extractvalue(column_value,'/x')
      FROM t,
     TABLE(xmlsequence(extract(xmltype('<list><x>'||REPLACE(c,', ','</x><x>')||'</x></list>'),
          '/list/x')))
     
    Cinq
    Deux
    Huit
    Quatre
    Sept
    Six
    Trois
    Un
    More Code : More Bugs. Less Code : Less Bugs
    Mon Blog PL/Sql : Fichier Zip / Image BMP / Lire sqliteDB / QRCode et Images PNG ou BMP

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

Discussions similaires

  1. Extraction d'une sous chaine numérique
    Par ouinih dans le forum PL/SQL
    Réponses: 4
    Dernier message: 10/02/2009, 11h29
  2. Extraction de chaine de caractères
    Par asterix76-rouen dans le forum Langage
    Réponses: 4
    Dernier message: 21/12/2006, 00h17
  3. Extraction de chiffres d'un champs VARCHAR vers un NUM
    Par midnight77 dans le forum MS SQL Server
    Réponses: 6
    Dernier message: 30/11/2004, 11h52
  4. [XSLT] Extraction de chaine de caractere
    Par Hugo001 dans le forum XSL/XSLT/XPATH
    Réponses: 11
    Dernier message: 28/10/2004, 09h27

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