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

Oracle Discussion :

Heure incohérente pour Oracle 8i, il est 16 H 60 !


Sujet :

Oracle

  1. #21
    Membre expert
    Avatar de LeoAnderson
    Profil pro
    Inscrit en
    Septembre 2004
    Messages
    2 938
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Septembre 2004
    Messages : 2 938
    Points : 3 199
    Points
    3 199
    Par défaut
    ça me semble plus simple de corriger le bug sous delphi (parce que s'en est un), quite à ne pas modifier le code et ensuite, de corriger les données par l'update +0.5 - 0.5
    mais ne partez surtout pas dans un trigger... ça serait désastreux pour les perfs

  2. #22
    Expert éminent sénior
    Avatar de orafrance
    Profil pro
    Inscrit en
    Janvier 2004
    Messages
    15 967
    Détails du profil
    Informations personnelles :
    Âge : 46
    Localisation : France

    Informations forums :
    Inscription : Janvier 2004
    Messages : 15 967
    Points : 19 073
    Points
    19 073
    Par défaut
    c'est peut-être un bug du connecteur... j'imagine que Delphi n'utilise pas la couche Net8 mais plutôt un driver de connexion type OCI ou ODBC non ?

  3. #23
    Nouveau membre du Club
    Inscrit en
    Octobre 2006
    Messages
    65
    Détails du profil
    Informations forums :
    Inscription : Octobre 2006
    Messages : 65
    Points : 30
    Points
    30
    Par défaut
    Citation Envoyé par orafrance Voir le message
    j'imagine que Delphi n'utilise pas la couche Net8 mais plutôt un driver de connexion type OCI ou ODBC non ?
    C'est le BDE, un équivalent...

    Mais si on oublie Delphi, quel est le moyen de reproduire ce pb sur une date ?

    Y a-t-il une façon connue de provoquer ce pb (chiffre > 60 dans champ 6 d'une date) ?

  4. #24
    Expert éminent sénior
    Avatar de orafrance
    Profil pro
    Inscrit en
    Janvier 2004
    Messages
    15 967
    Détails du profil
    Informations personnelles :
    Âge : 46
    Localisation : France

    Informations forums :
    Inscription : Janvier 2004
    Messages : 15 967
    Points : 19 073
    Points
    19 073
    Par défaut
    je connais aucun moyen de reproduire le problème puisque je ne l'ai jamais eu... sous SQL*Plus, c'est absolument impossible selon moi. Le problème dans ton cas c'est la transmission des données via BDE, c'est de ce coté que tu dois trouver un correctif

  5. #25
    Membre expert
    Avatar de LeoAnderson
    Profil pro
    Inscrit en
    Septembre 2004
    Messages
    2 938
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Septembre 2004
    Messages : 2 938
    Points : 3 199
    Points
    3 199
    Par défaut
    Citation Envoyé par zorino Voir le message
    C'est le BDE, un équivalent...

    Mais si on oublie Delphi, quel est le moyen de reproduire ce pb sur une date ?

    Y a-t-il une façon connue de provoquer ce pb (chiffre > 60 dans champ 6 d'une date) ?
    Quelle curieuse idée que de vouloir reproduire volontairement le problème au lieu de chercher à le corriger....
    Si vous voulez, vous pouvez toujours vous amuser à corrompre vos bases avec BBED mais ça ne résoudra pas vos soucis !

  6. #26
    Rédacteur

    Homme Profil pro
    Consultant / formateur Oracle et SQL Server
    Inscrit en
    Décembre 2002
    Messages
    3 460
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Var (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Consultant / formateur Oracle et SQL Server

    Informations forums :
    Inscription : Décembre 2002
    Messages : 3 460
    Points : 8 074
    Points
    8 074
    Par défaut
    Bonjour

    Au vu de la pièce jointe, moi je pencherais pour une problème côté Oracle, et pas du tout côté client.
    En effet, Oracle est censé effectuer un contrôle de validité avant d'accepter une valeur, en l'occurrence une date.
    Soit il a accepté une date invalide, et c'est une bogue, soit la date entrée était valide mais a été endommagée lors du stockage, ce qui serait également une bogue.

    Zorino : êtes vous capable, depuis votre application, d'entrer actuellement la date "18/09/2007 16:60:01" ?
    Etes-vous capable de le faire sous SQL*Plus ?

    Par ailleurs, si les dates ont été endommagées lors du stockage, vous pouvez peut-être les repérer en extrayant les différents composants de la date et en vérifiant s'ils sont dans la fourchette normale (par exemple les minutes entre 0 et 59).
    Consultant / formateur Oracle indépendant
    Certifié OCP 12c, 11g, 10g ; sécurité 11g

    Ma dernière formation Oracle 19c publiée sur Linkedin : https://fr.linkedin.com/learning/oracle-19c-l-administration

  7. #27
    Nouveau membre du Club
    Inscrit en
    Octobre 2006
    Messages
    65
    Détails du profil
    Informations forums :
    Inscription : Octobre 2006
    Messages : 65
    Points : 30
    Points
    30
    Par défaut
    Citation Envoyé par LeoAnderson Voir le message
    Quelle curieuse idée que de vouloir reproduire volontairement le problème au lieu de chercher à le corriger....
    Ben... Pour être franc, je sais pas comment tu corriges des pb de ce genre sans les reproduire !
    Un truc qui se produit 1 fois sur 1 million, pour lequel on a aucune certitude quant à l'origine, moi tant que je l'aurai pas reproduit, je serai pas certain de l'avoir corrigé.
    L'inconvénient étant que, même si ça arrive rarement, c'est assez grave pour le client lorsque ça se produit. Pas suffisamment à mon goût pour que je mette en place un trigger, et corriger le code prendrait 6 mois... alors je fais comme tu ferais sûrement à ma place, je me renseigne, je fouine !

  8. #28
    Nouveau membre du Club
    Inscrit en
    Octobre 2006
    Messages
    65
    Détails du profil
    Informations forums :
    Inscription : Octobre 2006
    Messages : 65
    Points : 30
    Points
    30
    Par défaut
    Citation Envoyé par Pomalaix Voir le message
    Au vu de la pièce jointe, moi je pencherais pour une problème côté Oracle, et pas du tout côté client.
    Je suis d'accord, ça n'est pas normal qu'une telle chose soit possible, de quelque façon que ce soit ! Personne n'a été modifier bit à bit le contenu de la base, pas de raison donc qu'elle soit corrompue...
    Par contre, je pense que l'origine du malaise est bel et bien dans le code...
    Le côté aléatoire fait assez penser aux problèmes de stockage des flottants, avec une imprécision minime, mais réelle quand même, qui pose peut-être pb à Oracle à une étape quelconque...

    En tous cas, ce qui est certain, c'est que la table ZCC a été créée par mes soins avec un champ DATE et que l'enregistrement donné en exemple a été innséré sous SQL*plus par INSERT INTO ZCC SELECT XXX FROM MATABLE WHERE DATEENERREUR, donc Oracle permet bel et bien de stocker une donnée pourrie et de la copier de table en table, ce qui ne me paraît pas normal...

    Citation Envoyé par Pomalaix Voir le message
    êtes vous capable, depuis votre application, d'entrer actuellement la date "18/09/2007 16:60:01" ?
    Etes-vous capable de le faire sous SQL*Plus ?
    Non, bien sûr, ça déclenche une erreur
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    ORA-01851: les minutes doivent être comprises entre 0 et 59
    Citation Envoyé par Pomalaix Voir le message
    vous pouvez peut-être les repérer en extrayant les différents composants de la date et en vérifiant s'ils sont dans la fourchette normale (par exemple les minutes entre 0 et 59).
    Pour info, c'est à la fois facile à repérer :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    SQL> select * from zcc where date1 like '00/%';
     
           IDF DATE1                DATEFLOAT
    ---------- ------------------- ----------
          1000 18/09/2007 16:60:01          0
    (car, en gros, la date équivaut à 00/00/0000)
    Et facile à corriger, voir posts précédents, il suffit de modifier la date, en utilisant toutefois des valeurs décimales (!) :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    UPDATE TABLE SET CHAMPDATE = CHAMPDATE + 0.5 - 0.5

  9. #29
    Expert éminent sénior
    Avatar de orafrance
    Profil pro
    Inscrit en
    Janvier 2004
    Messages
    15 967
    Détails du profil
    Informations personnelles :
    Âge : 46
    Localisation : France

    Informations forums :
    Inscription : Janvier 2004
    Messages : 15 967
    Points : 19 073
    Points
    19 073
    Par défaut
    A mon avis, y'a pas meilleure solution que créer un SR auprès du support...

  10. #30
    Rédacteur

    Homme Profil pro
    Consultant / formateur Oracle et SQL Server
    Inscrit en
    Décembre 2002
    Messages
    3 460
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Var (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Consultant / formateur Oracle et SQL Server

    Informations forums :
    Inscription : Décembre 2002
    Messages : 3 460
    Points : 8 074
    Points
    8 074
    Par défaut
    Citation Envoyé par LeoAnderson Voir le message
    Sur une 8i :
    [code]SQL> select dump(sysdate) from dual;

    DUMP(SYSDATE)
    --------------------------------------------------------------------------------
    Typ=13 Len=8: 7,215,11,28,6,53,38,0
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    DATE values are always stored in 7 bytes.
    Quand on regarde ces deux éléments, ça ne semble pas très cohérent !
    En creusant, je me rends compte que le résultat d'un SYSDATE n'est pas du même type ni du même format qu'une colonne de type DATE (et c'est toujours le cas en 10g et 11g).
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    SQL> select d, dump(d) interne, sysdate, dump(sysdate) interne from t;
     
    D                   INTERNE                                  SYSDATE             INTERNE
    ------------------- ---------------------------------------- ------------------- ----------------------------------------
    28/11/2007 14:22:54 Typ=12 Len=7: 120,107,11,28,15,23,55     28/11/2007 14:22:56 Typ=13 Len=8: 215,7,11,28,14,22,56,0
    La colonne date est de type 12, sur 7 octets et codée avec "une unité en excès" (14H22:54 est enregistré comme 15H23:55)
    alors que
    le résultat de la fonction SYSDATE, avant stockage, est de type 13 (non documenté), sur 8 octets, et codé en valeurs réelles.

    Tout ça ne faire guère progresser la science, mais souligne qu'on ne peut pas comparer une date stockée et une date non stockée à l'aide de la fonction DUMP.
    Consultant / formateur Oracle indépendant
    Certifié OCP 12c, 11g, 10g ; sécurité 11g

    Ma dernière formation Oracle 19c publiée sur Linkedin : https://fr.linkedin.com/learning/oracle-19c-l-administration

  11. #31
    Expert éminent sénior
    Avatar de orafrance
    Profil pro
    Inscrit en
    Janvier 2004
    Messages
    15 967
    Détails du profil
    Informations personnelles :
    Âge : 46
    Localisation : France

    Informations forums :
    Inscription : Janvier 2004
    Messages : 15 967
    Points : 19 073
    Points
    19 073
    Par défaut
    attention, SYSDATE est une fonction

  12. #32
    McM
    McM est déconnecté
    Expert éminent

    Homme Profil pro
    Développeur Oracle
    Inscrit en
    Juillet 2003
    Messages
    4 580
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Développeur Oracle

    Informations forums :
    Inscription : Juillet 2003
    Messages : 4 580
    Points : 7 740
    Points
    7 740
    Billets dans le blog
    4
    Par défaut
    Question con : Pour le SR, la 8i est encore maintenue ?

    Sinon, il y avait eu un post sur le pb de date 00/00/0000 qui plantait toad.

    Ca donnerait ça:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    SELECT DUMP(TO_DATE('01.01.0001', 'DD.MM.YYYY') - 1) 
    FROM dual
     
    Typ=13 Len=8: 0,0,12,31,0,0,0,0
    More Code : More Bugs. Less Code : Less Bugs
    Mon Blog PL/Sql : Fichier Zip / Image BMP / Lire sqliteDB / QRCode et Images PNG ou BMP

  13. #33
    Nouveau membre du Club
    Inscrit en
    Octobre 2006
    Messages
    65
    Détails du profil
    Informations forums :
    Inscription : Octobre 2006
    Messages : 65
    Points : 30
    Points
    30
    Par défaut
    Citation Envoyé par McM Voir le message
    Ca donnerait ça:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    SELECT DUMP(TO_DATE('01.01.0001', 'DD.MM.YYYY') - 1) 
    FROM dual
     
    Typ=13 Len=8: 0,0,12,31,0,0,0,0
    J'avais vu, j'ai essayé sans pb chez moi
    Pour ce qui est du SR, je ne sais pas ce que ça veut dire mais je suppose qu'il s'agit de signaler le pb chez Oracle : je ne vais pas le faire car je n'ai pas mandat pour, il faut juste imaginer que je suis sur ce forum en catimini, on n'est pas supposés avoir internet dans mon entreprise (soupir)...

    L'erreur que renvoie TOAD pour mon champ vérolé est :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    '0.0' is not a valid timestamp
    Selon les cas, il peut se retrouver complètement vautré, je suis obligé de tuer la tâche...

  14. #34
    Membre expert
    Avatar de LeoAnderson
    Profil pro
    Inscrit en
    Septembre 2004
    Messages
    2 938
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Septembre 2004
    Messages : 2 938
    Points : 3 199
    Points
    3 199
    Par défaut
    Le problème provient du faite que pour les heures, minutes et secondes, il y a un offset entre la valeur "attendue" et la valeur stockée dans le champ :
    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
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
     
    SQL> create table scott.test_date (col1 date);
     
    Table created.
     
    SQL> insert into scott.test_date (COL1) values (to_date('02/04/2007 15:59:05', 'DD/MM/YYYY HH24:MI:SS'));
     
    1 row created.
     
    SQL> insert  into scott.test_date (COL1) values (to_date('02/04/2007 16:00:07', 'DD/MM/YYYY HH24:MI:SS'));
     
    1 row created.
     
    SQL> commit;
     
    Commit complete.
     
    SQL> alter session set nls_date_format='DD/MM/YYYY HH24:MI:SS';
     
    Session altered.
     
    SQL> select col1, dump(col1) from scott.test_date;
     
    COL1
    -------------------
    DUMP(COL1)
    --------------------------------------------------------------------------------
    02/04/2007 15:59:05
    Typ=12 Len=7: 120,107,4,2,16,60,6
     
    02/04/2007 16:00:07
    Typ=12 Len=7: 120,107,4,2,17,1,8
    et chez vous, sur vos données corrompues, on a :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    SQL> SELECT dump(date1) FROM zcc;
     
    DUMP(DATE1)
    ---------------------------------------------------------------
    Typ=12 Len=7: 120,107,9,18,17,61,2
    ce qui correspond bien à 16h60

    Voici mon hypothèse : la routine d'insertion dans la base Oracle via le BDE a pris en compte l'offset mais a buggé (genre un modulo 60 mal calculé)
    A 16h00, Delphi a du vouloir calculer l'offset :
    HH = (H mod 24) + 1 = 17
    MM = (M mod 60) + 1 = 61
    Comme Delphi, de part la conversion en chaine force manifestement l'écriture directement en "binaire", sans passer par les conversions et les fonctions de manipulation de date, il squizze ainsi les vérifications oracle (qui n'est alors dans ce cas, pas irréprochable, je le reconnais)
    D'où la donnée enregistrée 17 61. Ensuite, l'affichage de la date corrige l'offset "bêtement" et donne donc une heure de 16h60
    Par contre, dès que l'on travaille de nouveau sur les routines de manipulation, les mécanismes de vérifications entrent en oeuvre et corrigent comme ils peuvent, convertissant 61 minutes en 1heure et 1 minute, ce qui rajoute une heure à la date initiale.

    Le programme d'essai sous delphi devrait être assez simple à réaliser, il suffit je pense de reprendre le code avec la conversion sauvage pour insérer une heure pile "minutes=00".

  15. #35
    Nouveau membre du Club
    Inscrit en
    Octobre 2006
    Messages
    65
    Détails du profil
    Informations forums :
    Inscription : Octobre 2006
    Messages : 65
    Points : 30
    Points
    30
    Par défaut
    merci Leo pour cette analyse.
    J'avais bien dans l'idée de faire ce genre de test, mais sans conviction... Mais puisque tu as pris le temps de te pencher sur la question, je n'ai maintenant plus le choix, je vais le faire !

    Je donnerai les infos ici dans la journée...

  16. #36
    Rédacteur

    Homme Profil pro
    Consultant / formateur Oracle et SQL Server
    Inscrit en
    Décembre 2002
    Messages
    3 460
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Var (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Consultant / formateur Oracle et SQL Server

    Informations forums :
    Inscription : Décembre 2002
    Messages : 3 460
    Points : 8 074
    Points
    8 074
    Par défaut
    Citation Envoyé par LeoAnderson Voir le message
    ...Delphi...force manifestement l'écriture directement en "binaire", sans passer par les conversions et les fonctions de manipulation de date, il squizze ainsi les vérifications oracle
    Moi je ne miserais pas une demi cacahuète sur ce scénario.
    A ma connaissance, aucun mécanisme Oracle ne permet de contourner ces vérifications, et en outre j'imagine mal Borland se donner tant de mal pour réinventer la roue qui, par malchance, s'avérerait carrée.
    Consultant / formateur Oracle indépendant
    Certifié OCP 12c, 11g, 10g ; sécurité 11g

    Ma dernière formation Oracle 19c publiée sur Linkedin : https://fr.linkedin.com/learning/oracle-19c-l-administration

  17. #37
    Membre expert
    Avatar de LeoAnderson
    Profil pro
    Inscrit en
    Septembre 2004
    Messages
    2 938
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Septembre 2004
    Messages : 2 938
    Points : 3 199
    Points
    3 199
    Par défaut
    ben ça me semble pas évident non plus, mais au moins je cherche et propose des tests !

    ce qui est bizarre c'est ce double offset... et que la donnée même soit corrompue.

    On ne connait pas non plus le type d'objet delphi instancé... Si c'est le type standard (TTable) ou un dérivé, voir même un type "original" qui n'hériterait que de TObject par exemple.

  18. #38
    Nouveau membre du Club
    Inscrit en
    Octobre 2006
    Messages
    65
    Détails du profil
    Informations forums :
    Inscription : Octobre 2006
    Messages : 65
    Points : 30
    Points
    30
    Par défaut
    Bon, je viens de tester et retester... chou blanc !

    J'ai commencé par diviser le journée par secondes et utiliser la même méthode pour l'insertion (donc via le BDE, avec le principe "douteux" de conversion de la date en type Float qui est utilisé dans le programme en cause). J'insère 100 000 enregistrements pour être certains de couvrir plus qu'une journée -> rien, tout est OK, toutes les dates sont bonnes.

    Du coup, je divise la journée non plus en secondes mais en tranches plus fines, en utilisant un dénominateur à la con pour générer des nombres complpiqués en virgule flottante, j'insère 500 000 enregistrements pour générer suffisamment de cas différents -> pareil, aucun problème à signaler...

    Pour info, le BDE utilise des "SQL links" pour mettre à jour les bases, donc pour Oracle, l'entrée se fait bien via du SQL. Par contre je ne saurais rien dire des données passées dans la requête quant on convertit la datte en flottant. A mon avis, le pb vient bien de là. J'ai corrigé ces lignes de programme pour supprimer cette conversion et je ne peux donc pas garantir que ça va régler le problème, mais bon, j'aurais au moins fait quelque chose !!!

    En tous cas, merci pour votre aide !

  19. #39
    Expert éminent sénior
    Avatar de orafrance
    Profil pro
    Inscrit en
    Janvier 2004
    Messages
    15 967
    Détails du profil
    Informations personnelles :
    Âge : 46
    Localisation : France

    Informations forums :
    Inscription : Janvier 2004
    Messages : 15 967
    Points : 19 073
    Points
    19 073
    Par défaut
    Citation Envoyé par Pomalaix Voir le message
    Moi je ne miserais pas une demi cacahuète sur ce scénario.
    A ma connaissance, aucun mécanisme Oracle ne permet de contourner ces vérifications, et en outre j'imagine mal Borland se donner tant de mal pour réinventer la roue qui, par malchance, s'avérerait carrée.

    les OCI n'écrivent-ils pas directement la donnée brute en outrepassant les vérifs du kernel ?

    Je ne serais pas surpris qu'un driver de connexion buggué puisse générer des telles incohérences

  20. #40
    Nouveau membre du Club
    Inscrit en
    Octobre 2006
    Messages
    65
    Détails du profil
    Informations forums :
    Inscription : Octobre 2006
    Messages : 65
    Points : 30
    Points
    30
    Par défaut
    Citation Envoyé par LeoAnderson Voir le message
    Si c'est le type standard (TTable) ou un dérivé, voir même un type "original" qui n'hériterait que de TObject par exemple.
    C'est un TQuery standard.
    Si tu connais Delphi, voilà en gros ce qui est fait :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    Query.Open;
    Query.Insert;
    Query.FieldByName('MaDate').AsFloat := AutreQuery.FieldByName('AutreDate').AsFloat;
    Query.Post;
    Sachant que AutreDate est garanti sans problème, je ne vois pas où peut se situer le pb, mais j'ai entendu parler de pb de stockage des réels donc... J'ai remplacé ces AsFloat, de toutes façons incongrus, par des AsDateTime... On verra bien si ça change quelque chose.

    Merci pour ton aide.

Discussions similaires

  1. est ce qu'il existe un alternative pour oracle
    Par oussamajlidi dans le forum Oracle
    Réponses: 1
    Dernier message: 18/01/2012, 10h57
  2. Réponses: 22
    Dernier message: 14/09/2010, 16h27
  3. y-a-t-il un générateur pour Oracle ?
    Par bahia dans le forum Autres outils décisionnels
    Réponses: 3
    Dernier message: 27/08/2003, 09h07
  4. [Kylix] kylix + dbexpress pour oracle!!
    Par RezzA dans le forum EDI
    Réponses: 6
    Dernier message: 14/01/2003, 18h33

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