Oracle
 sql >> Base de données >  >> RDS >> Oracle

Corruption de la date Oracle lors de la mise à jour

MISE À JOUR :

Je ne trouve aucune référence publiée à ce type spécifique de corruption DATE sur le site de support Oracle. (C'est peut-être là, mes recherches rapides n'ont tout simplement pas abouti.)

  • Script Baddate pour vérifier la base de données pour les dates corrompues [ID 95402.1]
  • Bogue 2790435 :INSERT série avec SELECT parallèle et conversion de type peut insérer des données corrompues [ID 2790435.8]

La sortie de la fonction DUMP() indique que la valeur de date est effectivement invalide :

Typ=12 Len=7: 120,110,11,18,13,0,16 

Nous nous attendons à ce que l'octet des minutes soit une valeur comprise entre un et soixante, pas zéro.

Les 7 octets d'une valeur DATE représentent, dans l'ordre, le siècle (+100), l'année (+100), le mois, le jour, l'heure (+1), les minutes (+1), les secondes (+1).

La seule fois où j'ai vu des valeurs DATE invalides comme celle-ci lorsqu'une valeur DATE était fournie en tant que variable de liaison, à partir d'un programme Pro * C (où la valeur de liaison est fournie dans la représentation interne de 7 octets, en contournant entièrement les routines de validation normales qui récupérer les dates invalides, par exemple le 30 février)

Il n'y a aucune raison de s'attendre au comportement que vous voyez, étant donné la syntaxe Oracle que vous avez publiée.

Il s'agit soit d'une fausse anomalie (corruption de la mémoire ?) soit, si cela se répète, d'un défaut (bogue) dans le code Oracle. S'il s'agit d'une faille dans le code Oracle, les suspects les plus probables seraient les fonctionnalités "nouvelles" d'une version non corrigée.

(Je sais que CAST est une fonction SQL standard qui existe depuis des lustres dans d'autres bases de données. Je suppose que je suis de la vieille école et que je ne l'ai jamais introduite dans mon répertoire de syntaxe Oracle. Je ne sais pas de quelle version d'Oracle il s'agissait. introduit le CAST, mais je m'en serais abstenu dans la première version dans laquelle il est apparu.)

Le grand "drapeau rouge" (qu'un autre commentateur a noté) est que CAST( datecol AS DATE) .

Vous vous attendriez à ce que l'optimiseur traite cela comme équivalent à date_col ... mais l'expérience passée nous montre que TO_NUMBER( number_col ) est en fait interprété par l'optimiseur comme TO_NUMBER( TO_CHAR ( number_col ) ) .

Je soupçonne que quelque chose de similaire pourrait se produire avec ce CAST inutile.

Sur la base de cet enregistrement que vous avez montré, je soupçonne que le problème concerne les valeurs avec une valeur "59" pour les minutes ou les secondes, et éventuellement une valeur "23" pour les heures, seraient celles qui affichent l'erreur.

J'essaierais de vérifier les endroits où les minutes, les heures ou les secondes sont stockées sous la forme 0 :

SELECT id, DUMP(activitydate)
  FROM newtable
 WHERE DUMP(activitydate) LIKE '%,0,%' 
    OR DUMP(activitydate) LIKE '%,0'