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 :

l'utilisation des RegExp


Sujet :

SQL Oracle

  1. #1
    LEK
    LEK est déconnecté
    Membre éclairé
    Profil pro
    Inscrit en
    Mai 2005
    Messages
    715
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mai 2005
    Messages : 715
    Par défaut l'utilisation des RegExp
    Bonjour,
    j'essaye d'écrire une expression régulière pour valider le format d'un champ de type heure qui va de 00:00 à 36:59.
    Pour celà j'ai essayé vainement avec les scripts suivants :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
     
    -- Premier test
    select case when regexp_like('36:69' , '^([0-3])([0-9]):([0-5])([0-9])$'  ) then 'Match Found' else 'No Match Found' end as output from dual;
     
    -- Second test
    select case when regexp_like('37:59' ,'^[0-9]{1,2}:[0-9]{1,2}$') then 'Match Found' else 'No Match Found' end as output from dual;
    Mais sans grand résultat....
    Quelqu'un pourrait-il m'apporter la lumière sur mes erreurs ?

    Merci d'avance pour toute aide.

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

    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
    Billets dans le blog
    4
    Par défaut
    Il faut mettre des OR (|) pour gérer le fait que les trentaines ne s'arrêtent qu'à 6.
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
     
    SELECT duree, CASE WHEN REGEXP_LIKE(duree , '^([0-2][0-9])|(3[0-6]):[0-5][0-9]$'  ) THEN 'Match Found' ELSE 'No Match Found' END AS output 
    FROM (		SELECT '36:59' AS duree FROM dual 
    UNION ALL SELECT '36:69' AS duree FROM dual 
    UNION ALL SELECT '37:59' AS duree FROM dual 
    UNION ALL SELECT '23:45' AS duree FROM dual 
    )
     
    DUREE	OUTPUT
    36:59	Match Found
    36:69	No Match Found
    37:59	No Match Found
    23:45	Match Found
    Attention le code est faux, voir plus bas.

  3. #3
    Membre chevronné
    Profil pro
    Inscrit en
    Février 2010
    Messages
    412
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2010
    Messages : 412
    Par défaut
    Sinon on peut laisser Oracle le faire tout seul comme un grand.
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    TMP@MINILHC >select duree, case when to_date(duree,'mi:ss')<=to_date('36:59','mi:ss') then 'ok' else 'ko' end valid from(
      2             SELECT '36:59' AS duree FROM dual
      3  --UNION ALL SELECT '36:69' AS duree FROM dual
      4  UNION ALL SELECT '37:59' AS duree FROM dual
      5  UNION ALL SELECT '23:45' AS duree FROM dual
      6  );
     
    DUREE VA
    ----- --
    36:59 ok
    37:59 ko
    23:45 ok
    Surtout que ca empeche votre premier exemple avec 69secondes de passer

  4. #4
    Membre Expert Avatar de pacmann
    Homme Profil pro
    Consulté Oracle
    Inscrit en
    Juin 2004
    Messages
    1 626
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 44
    Localisation : France, Bas Rhin (Alsace)

    Informations professionnelles :
    Activité : Consulté Oracle
    Secteur : Distribution

    Informations forums :
    Inscription : Juin 2004
    Messages : 1 626
    Par défaut
    Salut

    Le problème Ram7s, c'est que si ce n'est pas format date (genre vraiment n''imp "mfoirjamfoi"), ça claque en exception sur le cast en date au lieu de juste renvoyer KO...

  5. #5
    Modérateur
    Avatar de Waldar
    Homme Profil pro
    Sr. Specialist Solutions Architect @Databricks
    Inscrit en
    Septembre 2008
    Messages
    8 454
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 47
    Localisation : France, Val de Marne (Île de France)

    Informations professionnelles :
    Activité : Sr. Specialist Solutions Architect @Databricks
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2008
    Messages : 8 454
    Par défaut
    Et le format ce serait HH24:MI, pas MI:SS, et de facto les heures >= 24 provoquent une erreur de format.

    La solution de McM me paraît la plus élégante.

  6. #6
    LEK
    LEK est déconnecté
    Membre éclairé
    Profil pro
    Inscrit en
    Mai 2005
    Messages
    715
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mai 2005
    Messages : 715
    Par défaut
    Super! Merci McM car je creusais effectivement du côté des regexp pour pouvoir effectuer plusieurs vérifications génériques... Cela dit Rams7s c'est une solution à laquelle je n'avais pas penser et qui est assez astucieuse (faire une vérif avec le format mi:ss!!)...

    Merci encore à tous pour votre aide!

  7. #7
    Membre chevronné
    Profil pro
    Inscrit en
    Février 2010
    Messages
    412
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2010
    Messages : 412
    Par défaut
    Bonjour,

    C'est pas que je veuille defendre ma solution a tout prix, mais:

    Les REGEX, c'est bien mais pas top. Par exemple, ici elle n'etait pas bonne du premier coup, si le prochain filtre c'est pour les duree entre 22:35 et 34:49, ca risque d'etre coton a ecrire et a maintenir pour LEK. Alors que lire directement 36:59, ca me donne des frissons dans le dos tellement c'est simple a comprendre et modifier si besoin.

    @pacman:
    Je suis d'accord, ca peut etre genant, j'ai du commenter un des tests de McM du coup.

    @Waldar:
    Le format, c'est celui qui va bien. On veux juste une base 60.
    Dans le meilleur des mondes, le client indique des besoins, pas des moyens techniques pour resoudre le probleme.

    Par contre, le truc qui peut faire la difference (en dehors du cas de pacman qui peut etre decisif), c'est le résultat avec un seul chiffre pour le premier membre:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    TMP@MINILHC >SELECT duree, CASE WHEN REGEXP_LIKE(duree , '^([0-2][0-9])|(3[0-6]):[0-5][0-9]$'  ) THEN 'Match Found' ELSE 'No Match Found' END AS outpu
    t,case when to_date(duree,'mi:ss')<=to_date('36:59','mi:ss') then 'ok' else 'ko' end valid
      2  FROM (     SELECT '04:59' AS duree FROM dual
      3  Union
      4  SELECT '4:59' AS duree FROM dual
      5  );
     
    DUREE OUTPUT         VA
    ----- -------------- --
    04:59 Match Found    ok
    4:59  No Match Found ok

  8. #8
    Modérateur
    Avatar de Waldar
    Homme Profil pro
    Sr. Specialist Solutions Architect @Databricks
    Inscrit en
    Septembre 2008
    Messages
    8 454
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 47
    Localisation : France, Val de Marne (Île de France)

    Informations professionnelles :
    Activité : Sr. Specialist Solutions Architect @Databricks
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2008
    Messages : 8 454
    Par défaut
    Citation Envoyé par Rams7s Voir le message
    @Waldar:
    Le format, c'est celui qui va bien. On veux juste une base 60.
    Dans le meilleur des mondes, le client indique des besoins, pas des moyens techniques pour resoudre le probleme.
    En fait j'étais passé à côté de l'intérêt de la solution à cause du mi:ss, mais après avoir compris j'aime beaucoup le côté astucieux de votre proposition.

  9. #9
    Expert confirmé Avatar de mnitu
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Octobre 2007
    Messages
    5 611
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Marne (Champagne Ardenne)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Octobre 2007
    Messages : 5 611
    Par défaut
    Bref, c'est vrai que la requête initiale devrait être corrigé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
    16
    17
    18
    19
    20
    21
    22
    23
     
    Connected to Oracle Database 10g Enterprise Edition Release 10.2.0.4.0 
    Connected as mni
     
    SQL> 
    SQL> SELECT duree,
      2         CASE
      3           WHEN REGEXP_LIKE(duree , '^([0-2][0-9])|(3[0-6]):[0-5][0-9]$'  ) THEN 'Match Found'
      4           ELSE 'No Match Found'
      5         END AS output
      6  FROM (SELECT '36x59' AS duree FROM dual
      7  UNION ALL SELECT '36:69' AS duree FROM dual
      8  UNION ALL SELECT '37:59' AS duree FROM dual
      9  UNION ALL SELECT '23x45' AS duree FROM dual
     10  )
     11  /
     
    DUREE OUTPUT
    ----- --------------
    36x59 No Match Found
    36:69 No Match Found
    37:59 No Match Found
    23x45 Match Found
    mais gérer le cas en question (4:59) ne pose pas de problème.
    Dans la vrai vie je n'aime pas les choses détournées de la manière proposé ici, pensez à la maintenance du code aussi.

  10. #10
    McM
    McM est déconnecté
    Expert confirmé

    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
    Billets dans le blog
    4
    Par défaut
    Houla.. mon erreur en effet, il manque une () sur le OR !!!!
    Edit : Je rajoute le cas du 1 seul chiffre au début

    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
    SELECT duree,
               CASE
                 WHEN REGEXP_LIKE(duree , '^(([0-2]?[0-9])|(3[0-6])):[0-5][0-9]$'  ) THEN 'Match Found'
                 ELSE 'No Match Found'
               END AS output
        FROM (SELECT '36x59' AS duree FROM dual
        UNION ALL SELECT '36:69' AS duree FROM dual
        UNION ALL SELECT '37:59' AS duree FROM dual
        UNION ALL SELECT '23x45' AS duree FROM dual
        UNION ALL SELECT '23:45' AS duree FROM dual
        UNION ALL SELECT '5:45' AS duree FROM dual
       )
     
    DUREE	OUTPUT
    36x59	No Match Found
    36:69	No Match Found
    37:59	No Match Found
    23x45	No Match Found
    23:45	Match Found
    5:45	Match Found

  11. #11
    Membre Expert Avatar de pacmann
    Homme Profil pro
    Consulté Oracle
    Inscrit en
    Juin 2004
    Messages
    1 626
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 44
    Localisation : France, Bas Rhin (Alsace)

    Informations professionnelles :
    Activité : Consulté Oracle
    Secteur : Distribution

    Informations forums :
    Inscription : Juin 2004
    Messages : 1 626
    Par défaut
    Du coup Ram7s, on peut envisager deux solutions :

    - L'une mixte qui valide le format par regexp, puis implémente la règle de gestion par comparaison (à noter qu'une fois le format valide, on peut comparer sans to_date en paddant avec 0) :

    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
     
    SELECT duree,
               CASE
                 WHEN REGEXP_LIKE(duree , '^([0-6]?[0-9]):[0-5][0-9]$'  ) 
                        THEN case when to_date(duree,'mi:ss')<=to_date('36:59','mi:ss') then 'Match found' else 'No Match Found' end 
                        || ' version 2 : '  || case when lpad(duree,5, '0')<='36:59' then 'Match found' else 'No Match Found' end
                 ELSE 'Invalid format'
               END AS output
        FROM (SELECT '36x59' AS duree FROM dual
        UNION ALL SELECT '36:69' AS duree FROM dual
        UNION ALL SELECT '37:59' AS duree FROM dual
        UNION ALL SELECT '23x45' AS duree FROM dual
        UNION ALL SELECT '23:45' AS duree FROM dual
        UNION ALL SELECT '5:45' AS duree FROM dual
       )
     
       select lpad('5:45',5, '0') from dual
    - Encapsuler ta formule dans une fonction, qui trappe l'erreur de conversion pour renvoyer "Invalid Format"

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

Discussions similaires

  1. regexp utilisant des multiples
    Par jige23 dans le forum Access
    Réponses: 2
    Dernier message: 03/03/2015, 10h08
  2. [Crystal Report] Utilisation des vues de sql serveur
    Par Olivierakadev dans le forum SAP Crystal Reports
    Réponses: 2
    Dernier message: 15/11/2002, 17h44
  3. [BCB5] Utilisation des Ressources (.res)
    Par Vince78 dans le forum C++Builder
    Réponses: 2
    Dernier message: 04/04/2002, 16h01

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