sql >> Database >  >> RDS >> Oracle

Oracle-datumcorruptie tijdens update

BIJWERKEN:

Ik vind geen gepubliceerde verwijzing naar dit specifieke type DATE-corruptie op de ondersteuningssite van Oracle. (Het kan er zijn, mijn snelle zoekopdrachten hebben het gewoon niet opgeleverd.)

  • Baddate-script om database te controleren op corrupte datums [ID 95402.1]
  • Bug 2790435 - Seriële INSERT met parallelle SELECT- en typeconversie kan corrupte gegevens invoegen [ID 2790435.8]

De uitvoer van de DUMP()-functie geeft aan dat de datumwaarde inderdaad ongeldig is:

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

We verwachten dat de minutenbyte een waarde tussen één en zestig moet zijn, niet nul.

De 7 bytes van een DATE-waarde vertegenwoordigen, in volgorde, eeuw(+100), jaar (+100), maand, dag, uur(+1), minuten(+1), seconden(+1).

De enige keer dat ik ongeldige DATE-waarden zoals deze heb gezien toen een DATE-waarde werd geleverd als een bindvariabele, vanuit een Pro*C-programma (waar de bindwaarde wordt geleverd in de interne 7-byteweergave, waarbij de normale validatieroutines die vang ongeldige datums op, bijv. 30 februari)

Er is geen reden om het gedrag dat u ziet te verwachten, gezien de Oracle-syntaxis die u hebt gepost.

Dit is ofwel een valse anomalie (geheugenbeschadiging?) Of als dit herhaalbaar is, dan is het een fout (bug) in de Oracle-code. Als het een fout in de Oracle-code is, zijn de meest waarschijnlijke verdachten "nieuwe" functies in een niet-gepatchte release.

(Ik weet dat CAST een standaard SQL-functie is die al eeuwen in andere databases bestaat. Ik denk dat ik ouderwets ben en het nog nooit in mijn Oracle-syntaxisrepertoire heb geïntroduceerd. Ik weet niet welke versie van Oracle dat was introduceerde de CAST, maar ik zou er vanaf gebleven zijn in de eerste release waarin het verscheen.)

De grote 'rode vlag' (die een andere commentator opmerkte) is dat CAST( datecol AS DATE) .

Je zou verwachten dat de optimizer dat als gelijkwaardig aan date_col behandelt ... maar ervaring uit het verleden leert ons dat TO_NUMBER( number_col ) wordt door de optimizer feitelijk geïnterpreteerd als TO_NUMBER( TO_CHAR ( number_col ) ) .

Ik vermoed dat er iets soortgelijks aan de hand is met die onnodige CAST.

Op basis van dat ene record dat u liet zien, vermoed ik dat het probleem ligt bij waarden met een waarde van "59" voor minuten of seconden, en mogelijk een waarde van "23" voor uren, die de fout vertonen.

Ik zou proberen te zoeken naar plaatsen waar de minuten, uren of seconden zijn opgeslagen als 0:

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


  1. Probleem met MySQL-impasse met InnoDB

  2. Sqlite-gegevens en automatisch gemaakte knoppen op ScrollPane

  3. Fouten bij het maken van de hoofdtekst van het Oracle-pakket

  4. Zoekwoord zoeken en rangschikken resultaat