bonjour les gens, voila je pense que tout est dans le topic.
j'ai beau chercher sur le forum je ne trouve pas de fonction pour tester si une date est valide ou pas, à croire que ça n'existe pas (plsql) :aie:
Version imprimable
bonjour les gens, voila je pense que tout est dans le topic.
j'ai beau chercher sur le forum je ne trouve pas de fonction pour tester si une date est valide ou pas, à croire que ça n'existe pas (plsql) :aie:
Code:
1
2
3
4
5
6
7
8
9
10 CREATE OR REPLACE FUNCTION wmc_f_test_date (p_date IN VARCHAR2, p_format IN VARCHAR2 DEFAULT 'DD/MM/RRRR') RETURN BOOLEAN IS v_date DATE; BEGIN v_date := TO_DATE(p_date, p_format); RETURN TRUE; EXCEPTION WHEN OTHERS THEN RETURN FALSE; END;
Code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15 BEGIN IF wmc_f_test_date('31.01.2007', 'DD.MM.YYYY') THEN dbms_output.put_line('31.01.2007' || ' Ok'); ELSE dbms_output.put_line('31.01.2007' || ' KO'); END IF; IF wmc_f_test_date('31.02.2007', 'DD.MM.YYYY') THEN dbms_output.put_line('31.02.2007' || ' Ok'); ELSE dbms_output.put_line('31.02.2007' || ' KO'); END IF; END;
Citation:
31.01.2007 Ok
31.02.2007 KO
En faisant mes tests j'ai trouvé hallucinant ce qu'oracle considère comme bon :
Code:
1
2 SELECT TO_DATE('31*0107', 'DD/MM/RRRR') FROM dual
8O Hallucinant !Citation:
Envoyé par McM
On pourrait ajouter dans la fonction de test une comparaison de la chaine passée en paramètre avec un TO_CHAR(TO_DATE()) de cette même chaîne avec le même format, pour vérifier que la chaîne est bien au format fourni :
Code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15 CREATE OR REPLACE FUNCTION wmc_f_test_date (p_date IN VARCHAR2, p_format IN VARCHAR2 DEFAULT 'DD/MM/RRRR') RETURN BOOLEAN IS v_date VARCHAR2(50); BEGIN v_date := TO_CHAR(TO_DATE(p_date, p_format), p_format); IF (v_date = p_date) THEN RETURN TRUE; ELSE RETURN FALSE; END IF; EXCEPTION WHEN OTHERS THEN RETURN FALSE; END;
rbaraerCode:
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 rbaraer@Ora10g> BEGIN 2 IF wmc_f_test_date('31.01.2007', 'DD.MM.YYYY') THEN 3 4 dbms_output.put_line('31.01.2007' || ' DD.MM.YYYY' || ' Ok'); 5 ELSE 6 dbms_output.put_line('31.01.2007' || ' DD.MM.YYYY' || ' KO'); 7 END IF; 8 9 IF wmc_f_test_date('31.02.2007', 'DD.MM.YYYY') 10 THEN 11 dbms_output.put_line('31.02.2007' || ' DD.MM.YYYY' || ' Ok'); 12 ELSE 13 dbms_output.put_line('31.02.2007' || ' DD.MM.YYYY' || ' KO'); 14 END IF; 15 16 IF wmc_f_test_date('31.01.2007', 'DD/MM/YYYY') 17 THEN 18 dbms_output.put_line('31.01.2007' || ' DD/MM/YYYY' || ' Ok'); 19 ELSE 20 dbms_output.put_line('31.01.2007' || ' DD/MM/YYYY' || ' KO'); 21 END IF; 22 23 IF wmc_f_test_date('31*0107', 'DD/MM/RRRR') 24 THEN 25 dbms_output.put_line('31*0107' || ' DD/MM/RRRR' || ' Ok'); 26 ELSE 27 dbms_output.put_line('31*0107' || ' DD/MM/RRRR' || ' KO'); 28 END IF; 29 END; 30 / 31.01.2007 DD.MM.YYYY Ok 31.02.2007 DD.MM.YYYY KO 31.01.2007 DD/MM/YYYY KO 31*0107 DD/MM/RRRR KO PL/SQL procedure successfully completed. rbaraer@Ora10g>
Salut,
Désolé de remonter, mais concernant le fait de tester la validité d'une date, n'existe-t-il vraiment pas une fonction en Oracle 10g qui le fait, à l'instar de la fonction ISDATE de MS SQL Server ?
:question:
Ben, une date est toujours valide, sinon, ce n'est pas une date.
:yaisse2:
Vérifier qu'une chaine de caractere correspond à une date donnée, il y a to_date, si cela déclenche une exception, c'est que la chaine ne correspond pas à une date, en tout cas, pas au format proposé.
Une fonction qui rend un booleen vrai si c'est une date, faux sinon... A ton avis, si cela existait, pense tu vraiment que les posteurs précédents proposeraient des fonctions PL pour le faire ?
Je ne suis pas spécialiste Oracle et suivre de près la sortie des nouvelles versions d'Oracle ne m'intéresse pas.
Néanmoins, je suis en droit d'imaginer qu'Oracle peut évoluer… ;)
bon, il n'existe pas de version toute cuite...
Si on est vraiment pervers, on peut le tenter en XML :aie:
Code:
1
2
3
4
5
6
7
8
9
10
11
12
13 create table t(d varchar2(100)); insert into t values ('2008-01-31'); insert into t values ('2008-02-31'); select d, xmlquery( 'let $i:=if($X castable as xs:date)then "TRUE" else "FALSE" return $i' passing sys_xmlgen(D) as x returning content ).getStringVal() isValidDate from t; D ISVALIDDATE ----------- ----------- 2008-01-31 TRUE 2008-02-31 FALSE
J'aime ! Est-ce performant ?
non, pas du tout :aie:
En java, personne ne veut essayer ?
(cela ne sera pas performant non plus !)
Bref, une solution non performante mais qui exploite d’une manière inhabituelle des autres fonctionnalités reste toujours intéressante. Merci Laurent.
Vu sur AksTom, il faut apparemment utiliser "FX" pour gérer ce genre de cas :
produit :Code:
1
2 SELECT TO_DATE('31*0107', 'DD/MM/RRRR') FROM dual; SELECT TO_DATE('31*0107', 'fxDD/MM/RRRR') FROM dual;
Citation:
TO_DATE('31*0107','DD/MM/RRRR')
-------------------------
31/01/07
Erreur commençant à la ligne 2 de la commande :
SELECT TO_DATE('31*0107', 'fxDD/MM/RRRR') FROM dual
Rapport d'erreur :
Erreur SQL : ORA-01861: le littéral ne concorde pas avec le format chaîne de caractères
01861. 00000 - "literal does not match format string"
*Cause: Literals in the input must be the same length as literals in
the format string (with the exception of leading whitespace). If the
"FX" modifier has been toggled on, the literal must match exactly,
with no extra whitespace.
*Action: Correct the format string to match the literal.