Ошибка ORA-01438: value larger than specified precision в Oracle DB
- Ошибка
ORA-01438: value larger than specified precision allowed for this columnпри вставке или обновлении числовых полей. - Сбой пакетного импорта данных, интеграций с внешними API и расчетов итоговых сумм.
- Числовое значение превышает установленный лимит разрядности
NUMBER(precision, scale).
1. Определение разрядности целевой колонки
SELECT column_name, data_type, data_precision, data_scale
FROM all_tab_columns
WHERE table_name = 'MY_TABLE'
AND column_name = 'PRICE_COL';Справка: Для NUMBER(5, 2) максимальное число равно 999.99 (всего 5 цифр, из них 2 знака после запятой). Попытка вставить 1000.00 вызовет ORA-01438.
2. Увеличение разрядности колонки (Precision)
-- Расширение типа до 10 знаков (из них 2 знака после запятой)
ALTER TABLE my_table MODIFY (price_col NUMBER(10, 2));
-- Или снятие ограничений точности (хранение любого числа в пределах 38 знаков)
ALTER TABLE my_table MODIFY (price_col NUMBER);3. Округление и валидация данных перед вставкой
INSERT INTO my_table (price_col)
VALUES (ROUND(:input_val, 2)); Частые вопросы (FAQ)
Вызывает ли вставка числа с лишними знаками после запятой ошибку ORA-01438?
Нет. Если превышен только scale (знаки после запятой), Oracle автоматически выполняет округление (ROUND). Ошибка ORA-01438 возникает только тогда, когда превышено количество цифр в целой части (Precision - Scale).
Можно ли уменьшить разрядность колонки, если в таблице уже есть данные?
Oracle разрешает уменьшать точность (Precision/Scale) только в том случае, если таблица пуста, колонка содержит только NULL или фактические значения не превышают новый меньший размер.
Как найти строку во входящем файле ETL, вызвавшую ORA-01438?
Используйте директиву LOG ERRORS INTO с пакетом DBMS_ERRLOG. Все конфликтующие строки запишутся в таблицу ошибок с указанием значения.
В чем разница между типами FLOAT и NUMBER в контексте ORA-01438?
Тип NUMBER оперирует десятичной разрядностью. Тип FLOAT в Oracle задается в двоичной точности (Binary Precision). FLOAT не выдает ORA-01438 при выходе за пределы формата, а теряет точность младших разрядов.