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

JDBC Java Discussion :

Problème insertion date


Sujet :

JDBC Java

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre averti
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Février 2012
    Messages
    15
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Algérie

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : Distribution

    Informations forums :
    Inscription : Février 2012
    Messages : 15
    Par défaut Problème insertion date
    Bonjour.

    Je suis entrain de développer une application en java connectée à une bd Oracle8i via ojdbc14.
    la date de mon pc est configurer à GMT +1 ainsi que celle du serveur de bd.
    le problème que je rencontre est que lors d'une insertion d'une date (ex: sysdate), au niveau de la bd j’obtiens date - 1 heure (GMT).

    la question est : est-ce qu'il y a une configuration spécifique pour régler ce problème.

    Salutations et merci d'avance.

  2. #2
    Expert éminent
    Avatar de tchize_
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Avril 2007
    Messages
    25 482
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 45
    Localisation : Belgique

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

    Informations forums :
    Inscription : Avril 2007
    Messages : 25 482
    Par défaut
    code qui reproduit le problème STP.

    Le serveur s'en fou de son GMT local, il va toujours stocker les timestamp dans un format indépendant de la timezone.
    En fonction de la timezone de l'utilisateur, les timestamp s'afficheront donc différent pour une même donnée stockée dans la DB
    Si tu as un soucis d'heure, c'est vraisemblablement que tu stocker un timestamp là où tu voulais une date => met à jour to schéma de table, stocke une date si c'est une date.

  3. #3
    Membre averti
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Février 2012
    Messages
    15
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Algérie

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : Distribution

    Informations forums :
    Inscription : Février 2012
    Messages : 15
    Par défaut
    voilà mon code :
    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
     //encodeglb_dtime est une fonction qui encode un timestamp sous le format 'yyyy/mm/dd hh24:mi:ss'
    private static final String SQL = "INSERT INTO matable(num, nom, glb_dtime) VALUES (?, ?, encodeglb_dtime( to_date( ?, 'yyyy/mm/dd hh24:mi:ss' ) ) )";
    Connection con = null;
    PreparedStatement pres = null;
    try {
    	Class.forName("oracle.jdbc.driver.OracleDriver");
    	con = DriverManager.getConnection("jdbc:oracle:thin:@serveurdbip:1521:sid", "username","password");
    	pres = con.prepareStatement(SQL);
    	pres.setInt( 1, 999 );
    	pres.setString( 2, "nom" );
    	pres.setString( 3, getTimeStamp() );
    	pres.executeUpdate();
    } catch (SQLException e) {
    	// bla bla
    }
    static String getTimeStamp(){
            //org.joda.time.DateTime
        	DateTime now = new DateTime();
        	Timestamp time = new Timestamp( now.getMillis() );
            DateFormat glbdtimeFormat = new SimpleDateFormat( "yyyy/MM/dd HH:mm:ss" );
            return glbdtimeFormat.format( time );
    }
    le problème est que quand j'affiche le timestamp j'obtiens la même heure que celle du système (client ou serveur puisqu'il sont synchronisés à GMT +1)
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    System.out.println( getTimeStamp() );
    mais quand je fais appel à l'info insérée en PL/SQL j'obtiens le glb_dtime à h-1 (GMT)
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
     
    -- décodeglb_dtime(glb_dtime) est la fonction inverse de encodeglb_dtime()
    SELECT num, nom, décodeglb_dtime(glb_dtime) FROM matable WHERE num = 999

  4. #4
    Membre Expert
    Avatar de eulbobo
    Homme Profil pro
    Développeur Java
    Inscrit en
    Novembre 2003
    Messages
    786
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : Développeur Java

    Informations forums :
    Inscription : Novembre 2003
    Messages : 786
    Par défaut
    Pourquoi ?

    POURQUOI?

    Pourquoi récupérer un timestamp (par Joda en plus...), le convertir en String et le passer dans ce format à la base qui va utiliser une fonction PL pour... pour quoi d'ailleurs, en refaire une date?

    Soit tu passes un objet Date (vu que tu veux juste la date du jour, et que au final tu veux stocker un objet date), soit dans ta requête tu mets un sysdate !
    Et quand tu récupères tes infos, tu auras tout et sans problème vu que tu ne convertira pas trois fois une donnée pour revenir à son type d'origine !

    Donc soit tu fais ça :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
     
    private static final String SQL = "INSERT INTO matable(num, nom, glb_dtime) VALUES (?, ?, sysdate ) )";
     
    try (Connection con = DriverManager.getConnection("jdbc:oracle:thin:@serveurdbip:1521:sid", "username","password");
         PreparedStatement pres = con.prepareStatement(SQL);){
    	pres = con.prepareStatement(SQL);
    	pres.setInt( 1, 999 );
    	pres.setString( 2, "nom" );
    	pres.executeUpdate();
    } catch (SQLException e) {
    	// bla bla
    }
    Soit tu fais ça :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
     
    private static final String SQL = "INSERT INTO matable(num, nom, glb_dtime) VALUES (?, ?, ?) )";
     
    try (Connection con = DriverManager.getConnection("jdbc:oracle:thin:@serveurdbip:1521:sid", "username","password");
         PreparedStatement pres = con.prepareStatement(SQL);){
    	pres.setInt( 1, 999 );
    	pres.setString( 2, "nom" );
    	pres.setDate( 3, new Date() );
    	pres.executeUpdate();
    } catch (SQLException e) {
    	// bla bla
    }

    Accessoirement, si tu es en Java7, tu n'as plus besoin de faire un Class.forName pour charger le driver (le DriverManager sait se démerder tout seul maintenant), et il faut FERMER ses ressources
    (je change le code dans ce sens)


    (excusez mon ton énervé, mais c'est pas la première fois que je passe derrière du code ou quelqu'un a cru qu'il serait une bonne idée de convertir 12 fois des objets contenant des dates entre un format Date et un format String tout ça pour enregistrer une date au final... Code pour rien, générateur de bugs, compliqué de voir si ça a un sens, ...)

  5. #5
    Membre averti
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Février 2012
    Messages
    15
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Algérie

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : Distribution

    Informations forums :
    Inscription : Février 2012
    Messages : 15
    Par défaut
    Citation Envoyé par eulbobo Voir le message
    Pourquoi ?

    POURQUOI?

    Pourquoi récupérer un timestamp (par Joda en plus...), le convertir en String et le passer dans ce format à la base qui va utiliser une fonction PL pour... pour quoi d'ailleurs, en refaire une date?

    Soit tu passes un objet Date (vu que tu veux juste la date du jour, et que au final tu veux stocker un objet date), soit dans ta requête tu mets un sysdate !
    Et quand tu récupères tes infos, tu auras tout et sans problème vu que tu ne convertira pas trois fois une donnée pour revenir à son type d'origine !

    Donc soit tu fais ça :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
     
    private static final String SQL = "INSERT INTO matable(num, nom, glb_dtime) VALUES (?, ?, sysdate ) )";
     
    try (Connection con = DriverManager.getConnection("jdbc:oracle:thin:@serveurdbip:1521:sid", "username","password");
         PreparedStatement pres = con.prepareStatement(SQL);){
    	pres = con.prepareStatement(SQL);
    	pres.setInt( 1, 999 );
    	pres.setString( 2, "nom" );
    	pres.executeUpdate();
    } catch (SQLException e) {
    	// bla bla
    }
    Soit tu fais ça :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
     
    private static final String SQL = "INSERT INTO matable(num, nom, glb_dtime) VALUES (?, ?, ?) )";
     
    try (Connection con = DriverManager.getConnection("jdbc:oracle:thin:@serveurdbip:1521:sid", "username","password");
         PreparedStatement pres = con.prepareStatement(SQL);){
    	pres.setInt( 1, 999 );
    	pres.setString( 2, "nom" );
    	pres.setDate( 3, new Date() );
    	pres.executeUpdate();
    } catch (SQLException e) {
    	// bla bla
    }

    Accessoirement, si tu es en Java7, tu n'as plus besoin de faire un Class.forName pour charger le driver (le DriverManager sait se démerder tout seul maintenant), et il faut FERMER ses ressources
    (je change le code dans ce sens)


    (excusez mon ton énervé, mais c'est pas la première fois que je passe derrière du code ou quelqu'un a cru qu'il serait une bonne idée de convertir 12 fois des objets contenant des dates entre un format Date et un format String tout ça pour enregistrer une date au final... Code pour rien, générateur de bugs, compliqué de voir si ça a un sens, ...)
    Bonjour.
    Votre excuse est accepté.
    premièrement je ne suis pas un professionnel en java.
    je travail avec le jodatime pour profiter de ses point fort (comparaison de date, ajout des jour, ...), ce que j'ai poster n'est qu'un extrait de mon code.
    j'ai déjà essayé avec le sysdate mais dans la bd j'obtiens toujours heure -1, par contre si j’exécute cette requête directement sur pl/sql ça s’insère correctement (heure juste). c'est pour ça que j'ai employé jodatime, j'ajoute une heure de plus puis l’exécution de la requête me retourne heure juste :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
     
    // j'ajoute une heure a l'instant actuel.
    TimeStamp ts = new Timestamp(  new DateTime().plusHours(1).getMillis() );
    // ts reçoit alors un timestamp sous la forme : yyyy-mm-dd hh:mm:ss.fffffffff (heure actuelle +1 )
    // la fonction encodeglb(Date arg) que j'ai sous oracle accepte comme argument une date sous format : yyyy/MM/dd HH:mm:ss
    DateFormat glbdtimeFormat = new SimpleDateFormat( "yyyy/MM/dd HH:mm:ss" );
    String st = glbdtimeFormat.format( ts );
    pour votre 2ème proposition
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    pres.setDate( 3, new Date() );
    ça m'a déclenché l'erreur : java.sql.SQLException: ORA-01008: Toutes les variables ne sont pas liées

    merci d'avance.

  6. #6
    Membre Expert
    Avatar de eulbobo
    Homme Profil pro
    Développeur Java
    Inscrit en
    Novembre 2003
    Messages
    786
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : Développeur Java

    Informations forums :
    Inscription : Novembre 2003
    Messages : 786
    Par défaut
    On peut enregistrer des champs TimeStamp ou Date directement en base avec JDBC, il ne FAUT PAS les convertir en String avant. Que ce soit en lecture ou en écriture.

    Ensuite, le champ TimeStamp n'a d'intérêt que si tu veux conserver ou traiter avec les nanosecondes, d'après la conversion que tu fais, ce n'est pas le cas ! Utilise un type Date de bout en bout ! (en utilisant Joda pour la manipulation, mais Calendar est aussi efficace si tu veux juste ajouter/supprimer une heure. Joda permet d'avoir des fonctionnalités en plus si tu travailles sur les intervalles et les périodes, mais c'est intégré à Java8 avec la nouvelle API Date)

    Dans les deux exemples, la requête a une erreur : il y a une parenthèse fermante en trop à la fin (erreur dans le copier/coller).


    Essayes de manipuler des objets Date de bout en bout pour voir si tu as toujours le problème (et arrête le timestamp)

Discussions similaires

  1. Probléme Insertion Date
    Par Sceptique dans le forum JDBC
    Réponses: 10
    Dernier message: 10/05/2013, 17h30
  2. [A-03] Problème insert into et date
    Par thierrybatlle dans le forum Requêtes et SQL.
    Réponses: 3
    Dernier message: 20/10/2008, 08h17
  3. [MySQL] Affichage et insertion date ok,mais problème pour modifier
    Par philippef dans le forum PHP & Base de données
    Réponses: 1
    Dernier message: 08/07/2008, 08h07
  4. Problème insertion date dans base Access
    Par pep972 dans le forum JDBC
    Réponses: 2
    Dernier message: 13/06/2008, 11h15
  5. Problème insertion date sous MsSql
    Par MaitreTsiang dans le forum Zend Framework
    Réponses: 2
    Dernier message: 11/10/2007, 12h42

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