sql >> Databáze >  >> RDS >> Oracle

Poškození data Oracle během aktualizace

AKTUALIZACE:

Na stránkách podpory Oracle jsem nenašel žádný publikovaný odkaz na tento konkrétní typ poškození DATE. (Možná to tam je, moje rychlé vyhledávání to prostě nenašlo.)

  • Baddate Script pro kontrolu databází pro poškozená data [ID 95402.1]
  • Chyba 2790435 – Sériové INSERT s paralelním SELECT a převodem typu může vložit poškozená data [ID 2790435.8]

Výstup z funkce DUMP() ukazuje, že hodnota data je skutečně neplatná:

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

Očekáváme, že bajt minut by měl mít hodnotu mezi jednou a šedesáti, nikoli nulu.

7 bajtů hodnoty DATE představuje v pořadí století (+100), rok (+100), měsíc, den, hodinu (+1), minuty (+1), sekundy (+1).

Jediný případ, kdy jsem viděl neplatné hodnoty DATE, jako je tato, když byla hodnota DATE dodávána jako proměnná vazby, z programu Pro*C (kde je hodnota vazby dodávána v interní 7bajtové reprezentaci, což zcela obchází běžné ověřovací rutiny, které zachytit neplatná data, např. 30. února)

Vzhledem k vámi odeslané syntaxi Oracle není důvod očekávat chování, které vidíte.

Toto je buď falešná anomálie (poškození paměti?), nebo pokud je to opakovatelné, pak je to chyba (chyba) v kódu Oracle. Pokud se jedná o chybu v kódu Oracle, nejpravděpodobnějšími podezřelými by byly „nové“ funkce v neopravené verzi.

(Vím, že CAST je standardní funkce SQL, která se v jiných databázích používá už věky. Myslím, že jsem stará škola a nikdy jsem ji nezavedl do svého repertoáru syntaxe Oracle. Nevím, která verze Oracle to byla představil CAST, ale v prvním vydání, ve kterém se objevil, bych se od něj držel dál.)

Velká „červená vlajka“ (kterou zaznamenal jiný komentující) je, že CAST( datecol AS DATE) .

Očekávali byste, že to optimalizátor bude považovat za ekvivalent date_col ... ale minulé zkušenosti ukazují, že TO_NUMBER( number_col ) je ve skutečnosti optimalizátorem interpretováno jako TO_NUMBER( TO_CHAR ( number_col ) ) .

Mám podezření, že něco podobného se může odehrávat s tím nepotřebným CASTem.

Na základě toho jednoho záznamu, který jste ukázal, mám podezření, že problém je s hodnotami s hodnotou "59" pro minuty nebo sekundy a možná s hodnotou "23" pro hodiny, které by ukazovaly chybu.

Zkusil bych zkontrolovat místa, kde jsou minuty, hodiny nebo sekundy uloženy jako 0:

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


  1. Převeďte řetězec na hodnotu datetime v LINQ

  2. Chcete-li najít další pracovní den

  3. Odstraňte postavu z dané pozice na Oracle

  4. PHP/MySQL - Zvyšování názvu proměnné do smyčky pro data