Précédent   Forum des professionnels en informatique > Bases de données > Oracle > SQL
SQL Forum d'entraide sur le SQL pour Oracle
Partagez cette discussion sur d'autres réseaux sociaux : Viadeo Twitter Google Facebook Digg Delicious MySpace Yahoo
Réponse Proposer ce sujet en actualité
 
Outils de la discussion
Publicité
'
Vieux 31/01/2012, 16h14   #1
LEK
Membre éclairé
 
Inscription : mai 2005
Messages : 596
Détails du profil
Informations forums :
Inscription : mai 2005
Messages : 596
Points : 363
Points : 363
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 :
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.
LEK est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 31/01/2012, 16h26   #2
McM
Expert Confirmé Sénior
 
Inscription : juillet 2003
Messages : 3 440
Détails du profil
Informations forums :
Inscription : juillet 2003
Messages : 3 440
Points : 4 183
Points : 4 183
Il faut mettre des OR (|) pour gérer le fait que les trentaines ne s'arrêtent qu'à 6.
Code :
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.
__________________
More Code : More Bugs. Less Code : Less Bugs
McM est déconnecté   Envoyer un message privé Réponse avec citation 10
Vieux 31/01/2012, 17h34   #3
Membre expérimenté
 
François
Inscription : février 2010
Messages : 306
Détails du profil
Informations personnelles :
Nom : François

Informations forums :
Inscription : février 2010
Messages : 306
Points : 537
Points : 537
Sinon on peut laisser Oracle le faire tout seul comme un grand.
Code :
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
Rams7s est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 31/01/2012, 17h57   #4
Membre Expert
 
Avatar de pacmann
 
Homme Pacman Pacman
Business analyst
Inscription : juin 2004
Messages : 1 417
Détails du profil
Informations personnelles :
Nom : Homme Pacman Pacman
Âge : 31
Localisation : France, Paris (Île de France)

Informations professionnelles :
Activité : Business analyst
Secteur : Finance

Informations forums :
Inscription : juin 2004
Messages : 1 417
Points : 2 309
Points : 2 309
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...
__________________

(c'est ma photo)
Paku, Paku !
Pour les jeunes incultes : non, je ne suis pas un pokémon...

Le pacblog : http://pacmann.over-blog.com/
pacmann est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 31/01/2012, 18h06   #5
Modérateur
 
Homme Fabien
Ingénieur d'études en décisionnel
Inscription : septembre 2008
Messages : 5 686
Détails du profil
Informations personnelles :
Nom : Homme Fabien
Âge : 34
Localisation : France, Yvelines (Île de France)

Informations professionnelles :
Activité : Ingénieur d'études en décisionnel
Secteur : Arts - Culture

Informations forums :
Inscription : septembre 2008
Messages : 5 686
Points : 10 438
Points : 10 438
Envoyer un message via ICQ à Waldar Envoyer un message via Skype™ à Waldar
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.
__________________
Email : http://scr.im/waldar
Waldar est actuellement connecté   Envoyer un message privé Réponse avec citation 00
Vieux 31/01/2012, 20h23   #6
LEK
Membre éclairé
 
Inscription : mai 2005
Messages : 596
Détails du profil
Informations forums :
Inscription : mai 2005
Messages : 596
Points : 363
Points : 363
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!
LEK est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 02/02/2012, 10h52   #7
Membre expérimenté
 
François
Inscription : février 2010
Messages : 306
Détails du profil
Informations personnelles :
Nom : François

Informations forums :
Inscription : février 2010
Messages : 306
Points : 537
Points : 537
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 :
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
Rams7s est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 02/02/2012, 11h16   #8
Modérateur
 
Homme Fabien
Ingénieur d'études en décisionnel
Inscription : septembre 2008
Messages : 5 686
Détails du profil
Informations personnelles :
Nom : Homme Fabien
Âge : 34
Localisation : France, Yvelines (Île de France)

Informations professionnelles :
Activité : Ingénieur d'études en décisionnel
Secteur : Arts - Culture

Informations forums :
Inscription : septembre 2008
Messages : 5 686
Points : 10 438
Points : 10 438
Envoyer un message via ICQ à Waldar Envoyer un message via Skype™ à Waldar
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.
__________________
Email : http://scr.im/waldar
Waldar est actuellement connecté   Envoyer un message privé Réponse avec citation 00
Vieux 02/02/2012, 14h44   #9
Expert Confirmé Sénior
 
Avatar de mnitu
 
Homme Marius Nitu
Ingénieur développement logiciels
Inscription : octobre 2007
Messages : 3 313
Détails du profil
Informations personnelles :
Nom : Homme Marius Nitu
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 : 3 313
Points : 5 817
Points : 5 817
Bref, c'est vrai que la requête initiale devrait être corrigée
Code :
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.
mnitu est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 02/02/2012, 15h00   #10
McM
Expert Confirmé Sénior
 
Inscription : juillet 2003
Messages : 3 440
Détails du profil
Informations forums :
Inscription : juillet 2003
Messages : 3 440
Points : 4 183
Points : 4 183
Houla.. mon erreur en effet, il manque une () sur le OR !!!!
Edit : Je rajoute le cas du 1 seul chiffre au début

Code :
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
__________________
More Code : More Bugs. Less Code : Less Bugs
McM est déconnecté   Envoyer un message privé Réponse avec citation 20
Vieux 02/02/2012, 16h34   #11
Membre Expert
 
Avatar de pacmann
 
Homme Pacman Pacman
Business analyst
Inscription : juin 2004
Messages : 1 417
Détails du profil
Informations personnelles :
Nom : Homme Pacman Pacman
Âge : 31
Localisation : France, Paris (Île de France)

Informations professionnelles :
Activité : Business analyst
Secteur : Finance

Informations forums :
Inscription : juin 2004
Messages : 1 417
Points : 2 309
Points : 2 309
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 :
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"
__________________

(c'est ma photo)
Paku, Paku !
Pour les jeunes incultes : non, je ne suis pas un pokémon...

Le pacblog : http://pacmann.over-blog.com/
pacmann est déconnecté   Envoyer un message privé Réponse avec citation 00
Réponse Proposer ce sujet en actualité Cette discussion est résolue.
Outils de la discussion



Fuseau horaire GMT +2. Il est actuellement 11h22.


 
 
 
 
Partenaires

Hébergement Web