как сделать так, чтобы ora-01438 никогда не получалось: значение, превышающее указанную точность, разрешенную для этого столбца? - PullRequest
0 голосов
/ 09 января 2019

Я делаю деление для каждой записи и обновляю определенный столбец с результатом

так что мой sql выглядит примерно так

update table1 set frequency = num/denom where id>XXX

мой тип данных частоты - число (10,10)

На основании https://docs.oracle.com/cd/B28359_01/server.111/b28318/datatype.htm#CNCPT1838

Во-первых, я даже не уверен, почему я получаю эти данные, потому что ответ всегда будет 0.XXX, поэтому дайте 10 перед запятой будет много. Тогда 10 после запятой тоже должно быть в порядке, потому что оно будет усечено, если ответ будет больше.

Ответы [ 2 ]

0 голосов
/ 10 января 2019

NUMBER(10, 10) означает 10 цифр и шкалу 10.

Это означает, что у вас есть 10 цифр справа от десятичной точки, что означает нет цифра слева от нее.

Итак, имея таблицу

CREATE TABLE t
(
   test   NUMBER (10, 10)
);

insert into t values (0.9999999999); будет работать, а

insert into t values (0.99999999999); потерпит неудачу, поскольку значение округляется до 1.

Таким образом, если num/denom равно 1 или даже больше, вы получите ORA-01438: value larger than specified precision allowed for this column.

Но вы также получите эту ошибку, если num/denom больше 0.99999999995, поскольку оракул пытается округлить его до 1.

0 голосов
/ 10 января 2019

Прежде всего, позвольте мне разобраться с точностью и масштабом. Согласно документации указано:

Для числовых столбцов вы можете указать столбец как:

имя_ столбца NUMBER

При желании вы также можете указать точность (общее количество цифр) и масштаб (количество цифр справа от десятичная точка):

имя_ столбца NUMBER (точность, масштаб)

В вашем случае:

frequency NUMBER(10,10)

Это означает, что общее количество цифр равно 10, и это означает, что столбец может содержать значения из:

0.0000000001

до:

9999999999

Сюда входят целые числа до 9999999999 (10 девяток) и значения с плавающей запятой от 0,0000000001 (9 нулей и 1 в конце).

Теперь, когда мы это знаем, давайте перейдем к проблеме .. Вам нужен этот запрос, чтобы никогда не ошибаться с ORA-01438:

update table1 set frequency = num/denom where id>XXX;

Вы можете выполнить следующую проверку по времени обновления:

update table1
   set frequency = CASE LENGTH(TRUNC(num/denom)) >=10
                     THEN TRUNC(num/denom, 10)
                   ELSE
                     ROUND(num/denom), 10 - LENGTH(TRUNC(num/denom))) --TRUNC
                   END
 where id>XXX;

Что бы это сделать, это проверить: 1. Если вся часть деления больше или равна 10; в этом случае верните только первые 10 цифр (TRUNCATE). 2. Если вся часть меньше 10; в этом случае ROUND результат с десятичными разрядами "10 - LENGTH_OF_WHOLE_PART", но с точностью до 10, что соответствует столбцу.

* Примечание: ROUND выше на самом деле ROUND результат, что дает вам неточное значение. Если вам нужно получить необработанное усечение результата, используйте TRUNCATE вместо ROUND выше!

Приветствия

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...