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 21/12/2011, 10h59   #1
Membre à l'essai
 
Inscription : février 2005
Messages : 77
Détails du profil
Informations forums :
Inscription : février 2005
Messages : 77
Points : 24
Points : 24
Par défaut Mettre en forme une date

Bonjour

Je m’initie (avec plus ou moins de difficulté mais avec plaisir) depuis quelques temps à requêter des bases Oracles avec SQL_Developper.
Voilà qu’aujourd’hui, je suis confronté à un problème, sûrement simple, mais dont je n’arrive pas à trouver la solution.

C’est un problème de mise en forme de donnée.

Je récupère des valeurs représentant une date mais au format YYYYMMDD (ex : 20111221).
Ces valeurs sont insérées dans une table dont le champ est de type Varchar2 (8 byte)
L’insertion ne pose aucun problème. Je retrouve bien mes valeurs dans ma table au format YYYYMMDD.

Mais je souhaite dans un 1er temps affiché le contenu de ces dates dans un format plus lisible de type DD/MM/YYYY (ex : 21/12/2011)

J’ai essayé plusieurs synthaxe avec to_char ou to_date mais rien n’y fait.
Par exemple :
Code :
1
2
3
4
5
6
7
8
Select to_char(‘Ma_Date’,’YYYYMMDD’) from Ma_Table
Select to_char(Ma_Date,’YYYYMMDD’) from Ma_Table
Select to_date(‘Ma_Date’,’YYYYMMDD’) from Ma_Table
Select to_date(Ma_Date,’YYYYMMDD’) from Ma_Table

Des variantes avec des to_char et to_date imbriquées l’un dans l’autre
Mais rien n’y fait. Je n’ai pas de message d’erreur. Seulement, un affichage vide du résultat.

Je ne pense pas que la donnée insérée soit en cause car j'ai essayé sur une autre table avec des valeurs que j'ai insérée manuellement et là non plus, rien de rien...

J’avoue que je sèche un peu et je ne trouve pas mon erreur dans les tutos du site.

Si quelqu’un peut me conseiller, je suis preneur.

Bonne journée
francois78 est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 21/12/2011, 11h11   #2
Membre Expert
 
Avatar de lola06
 
Femme Laure
Consultante en Business Intelligence
Inscription : avril 2007
Messages : 983
Détails du profil
Informations personnelles :
Nom : Femme Laure
Âge : 25
Localisation : France, Alpes Maritimes (Provence Alpes Côte d'Azur)

Informations professionnelles :
Activité : Consultante en Business Intelligence
Secteur : Conseil

Informations forums :
Inscription : avril 2007
Messages : 983
Points : 1 693
Points : 1 693
Bonjour,

Tout d'abord tu as une erreur dans ta requête :

Code :
1
2
SELECT to_char(MaDate,'DD/MM/YYYY')
FROM MaTable
Il faut mettre le format que tu veux avoir et non pas le format que tu as déjà.

Si tu as un affichage vide c'est qu'il n'y a aucune ligne retournée. Peux-tu nous montrer ta requête complète ?
__________________
~ Lola ~

Ne pas oublier :
et aussi :
lola06 est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 21/12/2011, 11h23   #3
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
Citation:
table dont le champ est de type Varchar2 (8 byte)
Ton but est de transformer une chaine en date.. donc pas de TO_CHAR !

TO_DATE pour transformer une Chaine en Date
TO_CHAR pour transformer une Date en Chaine

poste le résultat de la requête suivante
Code :
SELECT madate, to_date(madate, 'YYYYMMDD') FROM matable WHERE rownum < 10
__________________
More Code : More Bugs. Less Code : Less Bugs
McM est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 21/12/2011, 11h25   #4
Membre régulier
 
Inscription : septembre 2008
Messages : 85
Détails du profil
Informations forums :
Inscription : septembre 2008
Messages : 85
Points : 89
Points : 89
Bonjour,

Comme les données d'origine ne sont pas stockées comme des dates, il faut peut être faire 2 conversions :

Code :
1
2
3
4
5
6
7
 
WITH t AS (
SELECT '20110101' a FROM dual union ALL
SELECT '20111201' a FROM dual union ALL
SELECT '20111231' a FROM dual 
)
SELECT TO_DATE(TO_DATE(A, 'yyyymmdd'), 'dd/mm/yyyy') FROM T
spdev666 est déconnecté   Envoyer un message privé Réponse avec citation 12
Vieux 21/12/2011, 11h25   #5
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
Oh non !! Jamais de to_date sur une date
__________________
More Code : More Bugs. Less Code : Less Bugs
McM est déconnecté   Envoyer un message privé Réponse avec citation 10
Vieux 21/12/2011, 11h33   #6
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 435
Points : 10 435
Envoyer un message via ICQ à Waldar Envoyer un message via Skype™ à Waldar
Citation:
Envoyé par francois78 Voir le message
Je récupère des valeurs représentant une date mais au format YYYYMMDD (ex : 20111221).
Ces valeurs sont insérées dans une table dont le champ est de type Varchar2 (8 byte)
C'est une des pires erreurs (et des plus courantes aussi) qu'il soit possible de faire en terme de base de données : ne pas utiliser le bon type.
Rien n'empêchera d'insérer la donnée 20111313 dans votre varchar.

Modifiez votre table, transformez votre colonne au format DATE.

Comme suggéré, vous devez faire une double conversion :
Code :
1
2
3
4
5
6
7
8
WITH t AS
(
SELECT '20110101' a FROM dual union ALL
SELECT '20111201'   FROM dual union ALL
SELECT '20111231'   FROM dual 
)
SELECT TO_CHAR(TO_DATE(A, 'yyyymmdd'), 'dd/mm/yyyy') AS dt
  FROM T;
__________________
Email : http://scr.im/waldar
Waldar est déconnecté   Envoyer un message privé Réponse avec citation 10
Vieux 21/12/2011, 11h44   #7
Membre Expert
 
Avatar de lola06
 
Femme Laure
Consultante en Business Intelligence
Inscription : avril 2007
Messages : 983
Détails du profil
Informations personnelles :
Nom : Femme Laure
Âge : 25
Localisation : France, Alpes Maritimes (Provence Alpes Côte d'Azur)

Informations professionnelles :
Activité : Consultante en Business Intelligence
Secteur : Conseil

Informations forums :
Inscription : avril 2007
Messages : 983
Points : 1 693
Points : 1 693
Autant pour moi, j'ai lu trop vite et n'avais pas bien vu le format de la colonne.

Par curiosité : est-il possible de faire directement :

Code :
1
2
 SELECT to_date(MaDate,'DD/MM/YYYY')
FROM MaTable
Est-ce qu'il reconnait de lui-même les DD, MM et YYYY ?
__________________
~ Lola ~

Ne pas oublier :
et aussi :
lola06 est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 21/12/2011, 11h54   #8
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
Non, le format de To_date correspond précisément à ce qu'il y a dans la colonne.. donc non oracle ne va pas deviner..
__________________
More Code : More Bugs. Less Code : Less Bugs
McM est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 21/12/2011, 12h58   #9
Expert Confirmé Sénior


 
Avatar de laurentschneider
 
Homme Laurent Schneider
Administrateur de base de données
Inscription : décembre 2005
Messages : 2 927
Détails du profil
Informations personnelles :
Nom : Homme Laurent Schneider
Localisation : Suisse

Informations professionnelles :
Activité : Administrateur de base de données
Secteur : Finance

Informations forums :
Inscription : décembre 2005
Messages : 2 927
Points : 4 549
Points : 4 549
parfois il devine quand même un tout petit peu ...

Code :
1
2
3
4
5
6
 
SQL> SELECT to_date('1-nov-1811','DD/MM/RR') FROM dual;
 
TO_DATE(1-NOV-1811
-------------------
1811-11-01_00:00:00
pour ces bizarreries, se référer à la doc :
http://docs.oracle.com/cd/E11882_01/...04.htm#g195479
__________________
Mon blog : laurentschneider.com
Mon livre : Advanced Oracle SQL Programming
laurentschneider est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 21/12/2011, 15h09   #10
Membre à l'essai
 
Inscription : février 2005
Messages : 77
Détails du profil
Informations forums :
Inscription : février 2005
Messages : 77
Points : 24
Points : 24
Ouahou!!!!!!! Je vois que ma demande déchaîne les passions !!

Après avoir lu quelques sujets sur différents forum, la maîtrise des données n'est pas acquise pour tout le monde, en particulier celle des conversion de date. Je parle pour moi bien sûr

Citation:
Envoyé par McM Voir le message
Ton but est de transformer une chaine en date.. donc pas de TO_CHAR !

TO_DATE pour transformer une Chaine en Date
TO_CHAR pour transformer une Date en Chaine

poste le résultat de la requête suivante
Code :
SELECT madate, to_date(madate, 'YYYYMMDD') FROM matable WHERE rownum < 10
En attendant vos réactions, j'essaie de suite et vous tiens au courant
Résultat
DATE_CREATION TO_DATE
---------------------- -------------------------
20110913 13/09/11
20101203 03/12/10
20070419 19/04/07
20110326 26/03/11
20101202 02/12/10
20101203 03/12/10
20110913 13/09/11
20110927 27/09/11
20110924 24/09/11

9 lignes sélectionnées


Mais en lisant et en relisant vos réponses, j'ai réfléchi avec ma tête et sur cette réponse ::
Citation:
Envoyé par Waldar Voir le message
C'est une des pires erreurs (et des plus courantes aussi) qu'il soit possible de faire en terme de base de données : ne pas utiliser le bon type.
Rien n'empêchera d'insérer la donnée 20111313 dans votre varchar.

Modifiez votre table, transformez votre colonne au format DATE.
En regardant de plus près ma table, j'ai une donnée dans mon champ VARCHAR2 = 0

Si je l'écarte alors ça marche beaucoup mieux

Pour résumé :
  1. Je transforme mon VARCHAR2 en DATE
  2. Au moment de l'insertion, je converti la donnée comme ceci :
Code :
1
2
INSERT INTO TO_CHAR(TO_DATE(A, 'yyyymmdd'), 'dd/mm/yyyy') AS dt
  FROM T;
En attendant vos réponse ou vos réactions, j'essaie et je vous tiens au courant.

A tout à l'heure
francois78 est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 21/12/2011, 16h31   #11
Membre à l'essai
 
Inscription : février 2005
Messages : 77
Détails du profil
Informations forums :
Inscription : février 2005
Messages : 77
Points : 24
Points : 24
Ca fonctionne mais pas du 1er coup.

Pourquoi ? Comme l'a très bien dit
Citation:
Envoyé par Waldar Voir le message
C'est une des pires erreurs (et des plus courantes aussi) qu'il soit possible de faire en terme de base de données : ne pas utiliser le bon type.
Rien n'empêchera d'insérer la donnée 20111313 dans votre varchar.
il faut donc maîtriser les données insérées dans une table.

Seulement, j'ai un cas particulier qui coince.

Je précise que je suis utilisateur habilité uniquement à requêter dans les bases ORACLE mais je ne recherche pas des problèmes de cohérence de donnée mais plutôt un dysfonctionnement de notre système. Toutefois, pour une obtenir un résultat exploitable issue de plusieurs tables, je créé mes propres tables et d'où ma question initiale sur le formatage de date.

Mon cas particulier est le suivant : je suis amené à requêter une table avec des champs contenant une date au format YYMMDD mais son type de data est VARCHAR2.
Sous certaines conditions, il est parfois logique qu'aucune date ne soit indiquée dans ce champ. Cela se traduit par une valeur = 00000000

Évidement, avec ce que nous avons vu ci-dessus, nous arrivons à la conclusion que nous ne pouvons pas insérer une telle valeur dans un champ date.

Et là, je bloque totalement

Dois je modifier ma requête ou dois je modifier les caractéristiques du champ DATE de ma table pour prendre en compte ce cas particulier ?

Je suis preneur de solutions diverses et variées.

Merci d'avance.
Bonne soirée
francois78 est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 21/12/2011, 16h38   #12
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 !

Pourquoi pas transformer ce pas de date en NULL ?

Code :
1
2
3
4
5
 
SELECT to_date(nullif(tadate,'00000000'), 'yymmdd')  
FROM (
    SELECT '20120101' tadate FROM dual union ALL
    SELECT '00000000' tadate FROM dual) t
__________________

(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 21/12/2011, 16h53   #13
Membre à l'essai
 
Inscription : février 2005
Messages : 77
Détails du profil
Informations forums :
Inscription : février 2005
Messages : 77
Points : 24
Points : 24
Pacmann

Tu m'as devancé mais je prends pour ma culture ton exemple que j'essaierai.

J'ai trouvé une autre solution avec un case :

Code :
1
2
3
4
case Ma_Date
when '00000000' then '01/01/01'
else TO_CHAR(TO_DATE(Ma_Date, 'yyyymmdd'), 'dd/mm/yyyy')
end
Si d'autres idées, exprimez vous.
La nuit porte conseil et je clôturais la demande demain matin

Bonne nuit
francois78 est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 21/12/2011, 17h00   #14
Membre Expert
 
Avatar de lola06
 
Femme Laure
Consultante en Business Intelligence
Inscription : avril 2007
Messages : 983
Détails du profil
Informations personnelles :
Nom : Femme Laure
Âge : 25
Localisation : France, Alpes Maritimes (Provence Alpes Côte d'Azur)

Informations professionnelles :
Activité : Consultante en Business Intelligence
Secteur : Conseil

Informations forums :
Inscription : avril 2007
Messages : 983
Points : 1 693
Points : 1 693
Le problème de ton case c'est que dans ton exemple tu remplace '00000000' par une date qui peut aussi apparaitre ailleurs dans ta base de données. Il vaut mieux remplacer par null.
Si tu tiens à utiliser le case alors la syntaxe c'est :

Code :
1
2
3
4
case Ma_Date
when '00000000' then NULL
else TO_CHAR(TO_DATE(Ma_Date, 'yyyymmdd'), 'dd/mm/yyyy')
end
__________________
~ Lola ~

Ne pas oublier :
et aussi :
lola06 est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 22/12/2011, 10h36   #15
Membre à l'essai
 
Inscription : février 2005
Messages : 77
Détails du profil
Informations forums :
Inscription : février 2005
Messages : 77
Points : 24
Points : 24
Bonjour à tous

Pour répondre à Lola06, la date du 01/01/01 ne peut apparaître ailleurs dans la mesure où mon SI n'existait pas à cette époque.

Mais rien n'est impossible. De plus, ta solution reflète plus la réalité car l'absence de date est le reflet des événements de notre SI.

J'ai testé et cela fonctionne.

Merci à tous et bonne journée

Et attention au chocolat pour les prochains jours....
francois78 est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 22/12/2011, 10h43   #16
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
Tout à fait, cela reflète mieux la réalité, et cela évite un certain nombre de désagréments de la valeur bidon.

Par exemple, les statistiques basiques te calculent le nombre de NULL sur une colonne, alors que pour prendre en compte le biais induit par une valeur bidon, il faut des histogrammes...
__________________

(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 22/12/2011, 13h43   #17
Expert Confirmé Sénior


 
Avatar de laurentschneider
 
Homme Laurent Schneider
Administrateur de base de données
Inscription : décembre 2005
Messages : 2 927
Détails du profil
Informations personnelles :
Nom : Homme Laurent Schneider
Localisation : Suisse

Informations professionnelles :
Activité : Administrateur de base de données
Secteur : Finance

Informations forums :
Inscription : décembre 2005
Messages : 2 927
Points : 4 549
Points : 4 549
ce qui est chouette c'est d'insérer des valeurs bidons dans la base, comme ça nous les DBA on a toujours du boulot

sqlplus 11.2.0.3
Code :
1
2
3
4
5
6
7
8
9
10
SQL> CREATE TABLE t(d date);
TABLE created.
SQL> INSERT INTO t VALUES (round(date '9999-12-31','MM'));
1 row created.
SQL> commit;
Commit complete.
SQL> SELECT d FROM t;
D
---------
01-JAN-00
Toad 11.1.0.17
Code :
1
2
3
4
5
6
7
8
9
10
SQL> CREATE TABLE t(d date)
TABLE created.
SQL> INSERT INTO t VALUES (round(date '9999-12-31','MM'))
1 row created.
SQL> commit
Commit complete.
SQL> SELECT d FROM t
D        
---------
01-JAN-01
La différence est subtile
__________________
Mon blog : laurentschneider.com
Mon livre : Advanced Oracle SQL Programming
laurentschneider est déconnecté   Envoyer un message privé Réponse avec citation 20
Vieux 22/12/2011, 14h19   #18
Membre Expert
 
Inscription : août 2008
Messages : 1 271
Détails du profil
Informations forums :
Inscription : août 2008
Messages : 1 271
Points : 1 928
Points : 1 928
Citation:
Envoyé par pacmann Voir le message
Par exemple, les statistiques basiques te calculent le nombre de NULL sur une colonne, alors que pour prendre en compte le biais induit par une valeur bidon, il faut des histogrammes...
D'autant que sans histogramme, la valeur bidon va perturber le calcul du facteur de filtrage pour les opérations de type range (>,< )
Citation:
Envoyé par laurentschneider Voir le message
La différence est subtile
C'est horrible ça...
skuatamad 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 05h36.


 
 
 
 
Partenaires

Hébergement Web