Oracle
 sql >> Datenbank >  >> RDS >> Oracle

Oracle-Datumsbeschädigung während des Updates

UPDATE:

Ich finde auf der Support-Website von Oracle keinen veröffentlichten Verweis auf diese spezielle Art von DATE-Beschädigung. (Möglicherweise ist es da, meine schnelle Suche hat es einfach nicht gefunden.)

  • Baddate-Skript zum Überprüfen der Datenbank auf beschädigte Daten [ID 95402.1]
  • Bug 2790435 – Serielles INSERT mit parallelem SELECT und Typkonvertierung kann beschädigte Daten einfügen [ID 2790435.8]

Die Ausgabe der Funktion DUMP() zeigt, dass der Datumswert tatsächlich ungültig ist:

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

Wir erwarten, dass das Minutenbyte einen Wert zwischen eins und sechzig haben sollte, nicht null.

Die 7 Bytes eines DATE-Werts repräsentieren in der Reihenfolge Jahrhundert (+100), Jahr (+100), Monat, Tag, Stunde (+1), Minuten (+1), Sekunden (+1).

Das einzige Mal, dass ich solche ungültigen DATE-Werte gesehen habe, als ein DATE-Wert als Bind-Variable von einem Pro * C-Programm bereitgestellt wurde (wobei der Bind-Wert in der internen 7-Byte-Darstellung bereitgestellt wird, wodurch die normalen Validierungsroutinen vollständig umgangen werden Fangen Sie ungültige Daten ab, z. B. 30. Februar)

Angesichts der von Ihnen geposteten Oracle-Syntax gibt es keinen Grund, das beobachtete Verhalten zu erwarten.

Dies ist entweder eine falsche Anomalie (Speicherbeschädigung?) Oder wenn dies wiederholbar ist, dann ist es ein Fehler (Bug) im Oracle-Code. Wenn es sich um einen Fehler im Oracle-Code handelt, wären die wahrscheinlichsten Verdächtigen "neue" Funktionen in einer ungepatchten Version.

(Ich weiß, dass CAST eine Standard-SQL-Funktion ist, die es schon seit Ewigkeiten in anderen Datenbanken gibt. Ich glaube, ich bin von der alten Schule und habe sie nie in mein Oracle-Syntax-Repertoire aufgenommen. Ich weiß nicht, welche Version von Oracle das war führte den CAST ein, aber ich hätte ihn in der ersten Veröffentlichung, in der er erschien, ferngehalten.)

Die große „rote Flagge“ (die ein anderer Kommentator bemerkte) ist, dass CAST( datecol AS DATE) .

Sie würden erwarten, dass der Optimierer dies als Äquivalent zu date_col behandelt ... aber die Erfahrung zeigt uns, dass TO_NUMBER( number_col ) wird vom Optimierer tatsächlich als TO_NUMBER( TO_CHAR ( number_col ) ) interpretiert .

Ich vermute, dass etwas Ähnliches mit diesem nicht benötigten CAST vor sich geht.

Basierend auf diesem einen Datensatz, den Sie gezeigt haben, vermute ich, dass das Problem bei Werten mit einem "59"-Wert für Minuten oder Sekunden und möglicherweise einem "23"-Wert für Stunden liegt, die den Fehler anzeigen würden.

Ich würde versuchen, nach Stellen zu suchen, an denen die Minuten, Stunden oder Sekunden als 0:

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