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

ORA-01873:špičková přesnost

Jedno z vašich číselných 'epoch' čísel se zdá být příliš velké (nebo příliš malé) pro numtodsinterval() funkci zvládnout. Nejvyšší hodnota, kterou můžete zadat jako počet sekund, je 2^31-1:

SQL> select numtodsinterval(power(2,31) - 1, 'SECOND') as interval from dual; 

INTERVAL     
--------------
24855 3:14:7.0

SQL> select numtodsinterval(power(2,31), 'SECOND') as interval from dual; 

SQL Error: ORA-01873: the leading precision of the interval is too small
01873. 00000 -  "the leading precision of the interval is too small"
*Cause:    The leading precision of the interval is too small to store the
           specified interval.
*Action:   Increase the leading precision of the interval or specify an
           interval with a smaller leading precision.

Jako epochu tento nejvyšší povolený počet sekund představuje 2038-01-19 03:14:07. Toto je problém roku 2038 , v podstatě.

Můžete se tam dostat i se záporným číslem:

SQL> select numtodsinterval(-2208988800, 'SECOND') as interval from dual;

SQL Error: ORA-01873: the leading precision of the interval is too small

Pomocí -power(2, 31) zabalí na kladnou hodnotu, ale chyby nižší než tato:

SQL> select numtodsinterval(power(2,31) - 1, 'SECOND') as interval from dual;

INTERVAL     
--------------
24855 3:14:7.0

SQL> select numtodsinterval(-power(2,31), 'SECOND') as interval from dual;

INTERVAL     
--------------
24855 3:14:8.0

SQL> select numtodsinterval(-power(2,31) - 1, 'SECOND') as interval from dual;

SQL Error: ORA-01873: the leading precision of the interval is too small

Dělíte 1000, takže jeden z vašich sloupců F až K má hodnotu, která přesahuje 2147483647000. To by mělo být docela snadné najít a možná budete chtít zvážit přidání kontrolního omezení do těchto sloupců, aby nebylo možné nastavit příliš vysoká – zkontrolujte, zda je hodnota sloupce menší nebo rovna 1000 * (power(2, 31) - 1) . A buď větší než nula, nebo větší než-1000 * (power(2, 31) taky.

Důvod, proč nedochází k chybě, když máte filtr jako where Col1 = 123 je, že váš filtr (predikát) je vložen do dotazu zobrazení a řádky s příliš vysokými hodnotami nejsou vyhodnoceny. Možná máte pouze jednu takovou hodnotu a její col1 hodnota není 123 a jeho col2 hodnota není 'xyz'. Pokud identifikujete problémový řádek a filtrujete pomocí jeho skutečného col1 hodnota bude stále chybová. Bez filtrů se vyhodnocení provádí pro všechny řádky.

Zdá se, že konkrétní záporné číslo, které máte, je magické číslo:

SQL> select date '1970-01-01' - 2208988800/86400 from dual;

DATE'1970-01-01'-2208988800/86400
---------------------------------
1900-01-01 00:00:00              

Pokud to chcete vyloučit, měli byste upravit definici pohledu tak, aby buď přidal filtr, např.:

...
AND tab2.colh > 0

nebo změňte sloupcový výraz tak, aby jej zpracovával, a to buď jeho rignorováním a ponecháním nulového, nebo pravděpodobně užitečnějším vrácením magického data:

    TO_CHAR(CASE WHEN tab2.colh = -2208988800000 THEN DATE'1900-01-01'
      ELSE DATE'1970-01-01' + NUMTODSINTERVAL( tab2.colh / 1000,'SECOND')
      END, 'YYYY/MM/DD HH24:MI:SS') AS Col13,

Můžete také přejít z používání intervalu na používání aritmetiky data:

    TO_CHAR(DATE'1970-01-01' + ( tab2.colh / 86400000 ), 'YYYY/MM/DD HH24:MI:SS') AS Col13,

Budete však muset upravit definici pohledu spíše než svůj dotaz, pokud není colh je zahrnuta ve výběrovém seznamu (což se nezdá být), a i kdyby tomu tak bylo, mohli byste jej pouze vyloučit - a to se nemusí vždy vyhnout chybě, v závislosti na tom, jak optimalizátor zpracoval dotaz.




  1. vložit databázi mysql do java aplikace

  2. DATETIMEOFFSETFROMPARTS() Příklady v SQL Server (T-SQL)

  3. ISDATE() Příklady v SQL Server

  4. pokus o export zdrojového kódu Java z databáze Oracle