Oracle
 sql >> база данни >  >> RDS >> Oracle

ORA-01873:водеща прецизност

Едно от вашите числови числа за „епоха“ изглежда твърде голямо (или твърде малко) за numtodsinterval() функция за обработка. Най-голямата стойност, която можете да подадете като брой секунди, е 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.

Като епоха този най-голям разрешен брой секунди представлява 2038-01-19 03:14:07. Това е проблемът от 2038 г. , по същество.

Можете да стигнете до там и с отрицателно число:

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

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

Използване на -power(2, 31) обвива до положителна стойност, но всичко по-ниско от това дава грешки:

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

Делите на 1000, така че една от вашите колони F до K има стойност, която надвишава 2147483647000. Това трябва да е доста лесно за намиране и може да помислите за добавяне на ограничение за проверка към тези колони, така че и те да не могат да бъдат зададени високо - проверете дали стойността на колоната е по-малка или равна на 1000 * (power(2, 31) - 1) . И или по-голямо от нула, или по-голямо от-1000 * (power(2, 31) също.

Причината да не дава грешка, когато имате филтър като where Col1 = 123 е, че вашият филтър (предикат) се избутва нагоре в заявката за изглед и редовете с твърде високи стойности не се оценяват. Може би имате само една такава стойност и нейната col1 стойността е не 123 и неговия col2 стойността е не "xyz". Ако идентифицирате проблемен ред и филтрирате, като използвате действителния му col1 стойност, пак ще има грешка. Без филтри оценката се извършва за всички редове.

Конкретното отрицателно число, което имате, изглежда е магическо число:

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

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

Ако искате да изключите това, тогава трябва да промените дефиницията на изгледа, за да добавите филтър, напр.:

...
AND tab2.colh > 0

или променете израза на колоната, за да се справите с него, или като го игнорирате и го оставите нула, или вероятно по-полезно да върнете тази магическа дата:

    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,

Можете също да промените от използване на интервал към използване на аритметика с дата:

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

Все пак ще трябва да промените дефиницията на изгледа, а не вашата заявка, освен ако colh е включено в списъка за избор (което изглежда не е) и дори да беше, можете само да го изключите - и това пак може да не избегне винаги грешката, в зависимост от това как оптимизаторът е обработил заявката.




  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Oracle Merge срещу Select then Insert или Update

  2. Декларирайте динамичен масив в Oracle PL/SQL

  3. Навигирайте от приложение A до приложение B със същите идентификационни данни - APEX 19.2

  4. Как да изброите всички изгледи в базата данни на Oracle

  5. динамична заявка в процедура на oracle с използване на курсор