UPPDATERING:
Jag hittar ingen publicerad referens till denna specifika typ av DATE-korruption på Oracles supportwebbplats. (Det kan finnas där, mina snabba sökningar visade det bara inte.)
- Baddate-skript för att kontrollera databas efter korrupta datum [ID 95402.1]
- Bug 2790435 – Serial INSERT med parallell SELECT och typkonvertering kan infoga korrupta data [ID 2790435.8]
Utdata från DUMP()-funktionen visar att datumvärdet verkligen är ogiltigt:
Typ=12 Len=7: 120,110,11,18,13,0,16
Vi förväntar oss att minutbyten ska vara ett värde mellan ett och sextio, inte noll.
De 7 byten av ett DATUM-värde representerar, i ordning, århundrade(+100), år(+100), månad, dag, timme(+1), minuter(+1), sekunder(+1).
Den enda gången jag har sett ogiltiga DATE-värden som detta när ett DATE-värde tillhandahölls som en bindningsvariabel, från ett Pro*C-program (där bindningsvärdet tillhandahålls i den interna 7-byte-representationen, helt förbi de normala valideringsrutinerna som fånga ogiltiga datum, t.ex. 30 februari)
Det finns ingen anledning att förvänta sig det beteende du ser, med tanke på Oracle-syntaxen du postade.
Detta är antingen en falsk anomali (minneskorruption?) eller om detta kan upprepas, så är det ett fel (bugg) i Oracle-koden. Om det är ett fel i Oracle-koden, skulle de mest troliga misstänkta vara "nya" funktioner i en icke-patchad version.
(Jag vet att CAST är en standard SQL-funktion som har funnits i evigheter i andra databaser. Jag antar att jag är gammal och har aldrig introducerat den i min Oracle-syntaxrepertoar. Jag vet inte vilken version av Oracle det var som introducerade CAST, men jag skulle ha hållit mig borta från den i den första releasen den dök upp i.)
Den stora "röda flaggan" (som en annan kommentator noterade) är att CAST( datecol AS DATE)
.
Du skulle förvänta dig att optimeraren skulle behandla det som likvärdigt med date_col ... men tidigare erfarenhet visar att TO_NUMBER( number_col )
tolkas faktiskt av optimeraren som TO_NUMBER( TO_CHAR ( number_col ) )
.
Jag misstänker att något liknande kan hända med den där onödiga CAST.
Baserat på den posten du visade, misstänker jag att problemet är med värden med ett "59"-värde för minuter eller sekunder, och möjligen ett "23"-värde för timmar, skulle vara de som visar felet.
Jag skulle försöka leta efter platser där minuterna, timmarna eller sekunderna lagras som 0:
SELECT id, DUMP(activitydate)
FROM newtable
WHERE DUMP(activitydate) LIKE '%,0,%'
OR DUMP(activitydate) LIKE '%,0'