Oracle
 sql >> Baza danych >  >> RDS >> Oracle

ORA-01873:wiodąca precyzja

Jedna z numerycznych liczb „epoki” wydaje się być za duża (lub za mała) dla numtodsinterval() funkcja do obsługi. Największa wartość, jaką możesz przekazać jako liczba sekund, to 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 epokę najwyższa dozwolona liczba sekund reprezentuje 2038-01-19 03:14:07. To jest problem roku 2038 , zasadniczo.

Możesz się tam również dostać z liczbą ujemną:

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

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

Używanie -power(2, 31) zawija do wartości dodatniej, ale wszystkie mniejsze błędy:

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

Dzielisz przez 1000, więc jedna z Twoich kolumn od F do K ma wartość przekraczającą 2147483647000. Powinno to być dość łatwe do znalezienia i warto rozważyć dodanie ograniczenia sprawdzającego do tych kolumn, aby nie można ich było również ustawić high - sprawdź, czy wartość kolumny jest mniejsza lub równa 1000 * (power(2, 31) - 1) . I albo większe niż zero, albo większe niż-1000 * (power(2, 31) też.

Powód, dla którego nie występuje błąd, gdy masz filtr taki jak where Col1 = 123 polega na tym, że filtr (predykat) jest wypychany do zapytania widoku, a wiersze ze zbyt wysokimi wartościami nie są oceniane. Być może masz tylko jedną taką wartość i jej col1 wartość to nie 123 i jego col2 wartość to nie „xyz”. Jeśli zidentyfikujesz wiersz problemu i przefiltrujesz przy użyciu jego rzeczywistego col1 wartość to nadal będzie błąd. Bez filtrów ocena jest wykonywana dla wszystkich wierszy.

Konkretna liczba ujemna, którą masz, wydaje się być liczbą magiczną:

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

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

Jeśli chcesz to wykluczyć, zmodyfikuj definicję widoku, aby dodać filtr, np.:

...
AND tab2.colh > 0

lub zmień wyrażenie kolumny, aby to obsłużyć, albo ignorując i pozostawiając wartość pustą, albo prawdopodobnie bardziej użytecznie zwracając tę ​​magiczną datę:

    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,

Możesz również zmienić użycie przedziału na arytmetykę dat:

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

Będziesz jednak musiał zmodyfikować definicję widoku, a nie zapytanie, chyba że colh znajduje się na liście wyboru (na którą nie wydaje się być), a nawet gdyby tak było, można go tylko wykluczyć – a to i tak nie zawsze może uniknąć błędu, w zależności od tego, jak optymalizator obsługiwał zapytanie.




  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Funkcja przechowywana w wywołaniu C# Oracle

  2. Oracle 11G - Efekt wydajności indeksowania przy wstawianiu

  3. Czy Oracle NetSuite Advanced PDF Template ma funkcje Group by i SUM?

  4. Błąd SQL - brak słowa kluczowego

  5. Uzyskaj tylko datę bez czasu w Oracle