Précédent   Forum des professionnels en informatique > Bases de données > DB2
DB2 Forum d'entraide technique sur la base de données DB2. Voir aussi -> Rubrique DB2
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 20/06/2007, 11h40   #1
Membre régulier
 
Inscription : juin 2007
Messages : 89
Détails du profil
Informations forums :
Inscription : juin 2007
Messages : 89
Points : 71
Points : 71
Par défaut Problème sur déchiffrage de date

Bonjour,

Je cherche à valider des dates stockées sous forme de char(8) au format 'YYYYMMDD'.

J'essaie donc de transformer le texte en date grace à cette petite transformation:

Code :
date(LEFT(DATEOV,4) || '-' || substr(DATEOV,5,2) || '-' || RIGHT(DATEOV,2))
Elle fonctionne très bien dans le select et place un null si la chaîne ne peut pas être convertie:

Code :
1
2
3
4
SELECT 
    date(LEFT(DATEOV,4) || '-' || substr(DATEOV,5,2) || '-' || RIGHT(DATEOV,2))
FROM
    xxx.yyy
Mais dès que j'essaie de mettre mon espression dans la clause where DB2 renvoie une erreur:

Code :
1
2
3
4
5
6
SELECT 
    date(LEFT(DATEOV,4) || '-' || substr(DATEOV,5,2) || '-' || RIGHT(DATEOV,2))
FROM
    xxx.yyy
WHERE 
    date(LEFT(DATEOV,4) || '-' || substr(DATEOV,5,2) || '-' || RIGHT(DATEOV,2))
====>

Code :
Error: java.sql.SQLException: [SQL0104] Elément syntaxique <FIN-INSTRUCTION> n'est pas correct. Eléments possibles : < > = <> <= !< !> != >= ¬< ¬> ¬= IN. Cause . . . . . : Une erreur de syntaxe a été détectée au niveau de l'élément <FIN-INSTRUCTION>. <FIN-INSTRUCTION> n'est pas un élément correct. < > = <> <= !< !> != >= ¬< ¬> ¬= IN est une liste partielle des éléments corrects. Cette liste suppose que l'instruction est correcte jusqu'à cet élément. L'erreur peut être située plus haut dans l'instruction, mais la syntaxe de l'instruction apparaît correcte jusqu'à ce point. Que faire . . . : Effectuez les opérations suivantes, puis renouvelez votre demande : - Vérifiez l'instruction au niveau de l'élément <FIN-INSTRUCTION>. Corrigez-la. Il peut s'agir d'une virgule ou de guillemets manquants, ou de clauses mal ordonnées. - Si l'erreur porte sur <FIN-INSTRUCTION>, corrigez l'instruction SQL qui ne se termine pas sur une clause correcte., SQL State: 42601, Error Code: -104
Alors je suis un peu perdu...

Pour infos, il s'agit d'un db2/400 (iSeries).
bleporini est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 20/06/2007, 16h15   #2
Membre du Club
 
Inscription : février 2007
Messages : 56
Détails du profil
Informations forums :
Inscription : février 2007
Messages : 56
Points : 56
Points : 56
Bonjour,

Dans ta requête...
Citation:
SELECT
date(LEFT(DATEOV,4) || '-' || substr(DATEOV,5,2) || '-' || RIGHT(DATEOV,2))
FROM
xxx.yyy
WHERE
date(LEFT(DATEOV,4) || '-' || substr(DATEOV,5,2) || '-' || RIGHT(DATEOV,2))
ne manque t'il pas un opérateur de comparaison dans ta clause WHERE ?
Ou alors, peut être que tu veux tester si la fonction DATE renvoie NULL ? Dans ce cas, il faut utiliser l'opérateur IS NULL ou IS NOT NULL (selon ce que tu veux).

X.
clalevee est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 20/06/2007, 17h14   #3
Membre régulier
 
Inscription : juin 2007
Messages : 89
Détails du profil
Informations forums :
Inscription : juin 2007
Messages : 89
Points : 71
Points : 71
Evidemment, j'en suis désolé ...

il fallait lire:

Code :
1
2
3
4
5
6
SELECT 
    date(LEFT(DATEOV,4) || '-' || substr(DATEOV,5,2) || '-' || RIGHT(DATEOV,2))
FROM
    xxx.yyy
WHERE 
    date(LEFT(DATEOV,4) || '-' || substr(DATEOV,5,2) || '-' || RIGHT(DATEOV,2)) IS NULL
et le bon message d'erreur est donc:

Code :
 [SQL0181] Une valeur de la chaîne date, heure ou horodatage est incorrecte. Cause . . . . . : La représentation dans la chaîne d'une valeur de date, d'heure ou d'horodatage ne se trouve pas dans la fourchette admise. *N est soit la constante (chaîne de caractères) incorrecte, soit la variable hôte ou la colonne qui contient cette chaîne. Si le nom est *N, la valeur a été trouvée dans une expression indiquée dans l'instruction. Si la valeur a été trouvée dans une variable hôte, celle-ci porte le numéro 0. Les fourchettes admises pour les valeurs de date, d'heure ou d'horodatage sont les suivantes : - Pour les années : de 0001 à 9999. - Pour les mois : de 1 à 12. - Pour les jours : de 1 à 30 pour avril, juin, septembre et novembre, de 1 à 28 pour février et de 1 à 31 pour tous les autres mois. En cas d'année bissextile, la fourchette pour février va de 1 à 29. - Pour les jours dans une date au format julien : de 001 à 366 pour une année bissextile et de 001 à 365 jours dans le cas contraire. - Pour les heures : de 0 à 24. Si l'heure est 24, alors les autres parties des valeurs TIME doivent être égales à zéro. Si le format d'heure est USA, la valeur maximale admise est 12. - Pour les minutes : de 0 à 59. - Pour les secondes : de 0 à 59. - Pour les microsecondes : de 0 à 999999. Que faire . . . : Assurez-vous que la valeur de date, d'heure ou d'horodatage est correcte pour le type de données qu'elle représente. Renouvelez votre demande., SQL State: 22007, Error Code: -181
bleporini est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 20/06/2007, 17h29   #4
Membre Expert
 
Inscription : novembre 2004
Messages : 1 298
Détails du profil
Informations forums :
Inscription : novembre 2004
Messages : 1 298
Points : 1 355
Points : 1 355
Quel est l'OS ?
Mercure est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 20/06/2007, 17h41   #5
Membre régulier
 
Inscription : juin 2007
Messages : 89
Détails du profil
Informations forums :
Inscription : juin 2007
Messages : 89
Points : 71
Points : 71
iSeries i5: Version 5 Release 3 Modification 0
bleporini est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 20/06/2007, 20h11   #6
Membre Expert
 
Inscription : novembre 2004
Messages : 1 298
Détails du profil
Informations forums :
Inscription : novembre 2004
Messages : 1 298
Points : 1 355
Points : 1 355
Code :
1
2
WHERE 
    date( ... ) = NULL
Mercure est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 21/06/2007, 09h01   #7
Membre régulier
 
Inscription : juin 2007
Messages : 89
Détails du profil
Informations forums :
Inscription : juin 2007
Messages : 89
Points : 71
Points : 71
Déjà essayé:

Citation:
[SQL0128] Utilisation de NULL incorrecte. Cause . . . . . : Le mot clé NULL ne peut pas être utilisé avec l'opérateur indiqué. Il n'est admis que dans un prédicat suivant IS ou IS NOT. NULL est un mot clé réservé et peut uniquement être utilisé comme nom de colonne si ce nom se trouve entre délimiteurs dans une instruction SQL. Que faire . . . : Vous devez soit remplacer l'opérateur par IS ou IS NOT, soit entrer le nom entre délimiteurs, si le mot NULL devait désigner une colonne., SQL State: 42601, Error Code: -128
bleporini est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 21/06/2007, 14h23   #8
Membre Expert
 
Inscription : novembre 2004
Messages : 1 298
Détails du profil
Informations forums :
Inscription : novembre 2004
Messages : 1 298
Points : 1 355
Points : 1 355
Par défaut Date "choucroutée"

Exact, je me suis trompé d'OS, désolé.

Mais, AMHA il y a de la choucroute dans la colonne DATEOV. Ce champ n'est pas nul et contient une date non conforme, par ex. mois = 13, année = ^^07, jour = 32, ou date = 21062007 au lieu de 20070621 ou autre fantaisie du même genre.
Mercure est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 21/06/2007, 14h51   #9
Membre régulier
 
Inscription : juin 2007
Messages : 89
Détails du profil
Informations forums :
Inscription : juin 2007
Messages : 89
Points : 71
Points : 71
C'est exactement le but de la requête, identifier les données non conformes.
D'ailleurs
renvoie null, c'est donc pour ça que je cherche à faire un test de nullité sur la valeur de cette expression.
bleporini est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 21/06/2007, 17h29   #10
Membre Expert
 
Inscription : novembre 2004
Messages : 1 298
Détails du profil
Informations forums :
Inscription : novembre 2004
Messages : 1 298
Points : 1 355
Points : 1 355
Utiliser cet artifice pour savoir si le contenu de la colonne est erroné me semble un tantinet risqué . Pour faire ce test, je préfère écrire une petite fonction en langage SQL et utiliser cette fonction dans ma requête SELECT.

Fonction DateErr
Code :
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
39
40
41
42
43
44
45
 
-- Mettre la bibliotheque objet en *CURLIB                              
-- avant de compiler avec RUNSQLSTM                                     
 
-- Paramètres:                                                          
--    InDate          : Date sur 8 caracteres alphanumériques                          
 
--===================================================================== 
 
DROP   FUNCTION DateErr                                        
 
CREATE FUNCTION DateErr                                               
  (InDate   Varchar (8))                                                
   Returns  Smallint                                                    
   LANGUAGE SQL                                                         
   Deterministic                                                        
   Contains SQL                                                         
   Returns NULL ON NULL Input                                  
   No External Action                                          
 
 Begin                                                          
 
      -- Local variables                                        
      Declare BoolErr Smallint;                                 
 
      SET BoolErr = 0; 
 
      -- Contrôle année                                                          
      IF   substr( InDate, 1, 4 ) NOT BETWEEN '0001' AND '9999' 
           Then SET BoolErr = -1;                                
      End IF;                                                   
 
      -- Conreôle mois                                                     
      IF   substr( InDate, 5, 2 ) NOT BETWEEN '01' AND '12'     
           Then SET BoolErr = -1;                                
      End IF;                                                   
 
      -- Contrôle jour                                                           
      IF   substr( InDate, 7, 2 ) NOT BETWEEN '01' AND '31'         
           Then SET BoolErr = -1;                                    
      End IF;                                                       
 
      RETURN BoolErr;     
 
 End
Une fonction de ce genre est vite écrite. Elle est facile à comprendre et rend de grands services. Elle n'est pas sensible à la casse des caractères et peut être écrite dans un langage quelconque supporté par la machine bien entendu.

On la place dans un membre source de type SQL dans le fichier source QSQLSRC qu'on crée au préalable si besoin avec la commande standard
Code :
CRTSRCPF FILE(MABIB/QSQLSRC)  RCDLEN(92) TEXT('Membres source SQL')
On compile ensuite ce membre avec la commande
Code :
 RUNSQLSTM SRCFILE(MABIB/QSQLSRC) SRCMBR(DATEERR) COMMIT(*NONE)
On corrige les éventuelles erreurs en allant voir le spool QSYSPRT.

Enfin, on utilise la fonction directement sur le prédicat WHERE et/ou dans la clause SELECT :
Code :
1
2
3
SELECT DATEOV, DATEERR(DATEOV), ...
FROM xxx/yyy
WHERE DATEERR(DATEOV) < 0
Mercure est déconnecté   Envoyer un message privé Réponse avec citation 00
Réponse Proposer ce sujet en actualité
Outils de la discussion



Fuseau horaire GMT +2. Il est actuellement 02h58.


 
 
 
 
Partenaires

Hébergement Web