ORA-01438:이 열에 대해 지정된 전체 자릿수보다 큰 값이 허용됩니다 오류를 해결하는 방법에 대해 알아보도록 합시다. 우선 해당 오류는 영어로 'ORA-01438: value larger than specified precision allowed for this column' 입니다. 그리고 오류의 핵심은 specified precision입니다. 다음을 기준으로 살펴보도록 하겠습니다.
- ORA-01438 : specified precision
- 오라클 NUMBER data type의 이해
ORA-01438:이 열에 대해 지정된 전체 자릿수보다 큰 값이 허용됩니다, 원인
SQL> INSERT INTO tablename (num) VALUES (1000);
INSERT INTO tablename (num) VALUES (1000)
*
1행에 오류:
ORA-01438: 이 열에 대해 지정된 전체 자릿수보다 큰 값이 허용됩니다.
해당 오류는 지정된 자릿수보다 큰 값을 입력하려고 시도하였기 때문입니다.
ORA-01438: value larger than specified precision allowed for this column, 해결하기
해당 오류를 해결하기 위한 방법은 크게 2가지가 있습니다. 하나는 자릿수를 늘리는 방법, 다른 하나는 반대로 자릿수를 줄이는 방법입니다.
컬럼의 데이터 타입을 확장하는 방법
ALTER TABLE tableName MODIFY columnName NUMBER(5, 2);
* NUMBER(5, 2)는 5자리의 전체 자릿수와 2자리의 소수점 자릿수를 의미합니다.
입력하려는 값의 자릿수를 줄이는 방법
데이터 타입의 조정이 힘든 상황이라면, 입력하려는 값의 자릿수를 줄이도록 해봅니다.
오라클 NUMBER data type의 이해
지정된 자릿수가 뭐길래 오류가 발생했을까요? 넘버 데이터타입을 이해해 보도록 합시다.
NUMBER 구성 요소
NUMBER[(precision [, scale])]
NUMBER는 precision과 scale로 구성됩니다. scale은 생략이 가능하다는 뜻으로 [, scale]과 같이 표기합니다.
precision 전체 자리수를 의미합니다.
여기서 말하는 전체 자릿수는 유효 숫자(significant digits)를 의미합니다. 실제 범위는 -10^125~10^125입니다.
scale은 소수점 자릿수를 의미하며 -84~127 범위로 음수 값이 가능한 게 특징입니다.
일반적으로 반올림처리가 되며, 생략 시 기본값은 0입니다.
ORA-01438 : value larger than specified precision allowed for this column
scale은 생략이 가능하다고 하였습니다. 결국 오류 내용에서 직접적으로 말하듯이
ORA-01438 오류는 NUMBER 타입 중 precision 때문에 발생합니다.
NUMBER 데이터 타입의 선언
precision과 scale을 모두 생략하는 경우
NUMBER => 적용 가능한 최대치를 precision과 scale에 모두 설정합니다.
scale을 생략하는 경우
- scale을 생략하는 경우, scale은 0으로 간주합니다. 스케일은 반올림 역할을 합니다.
- NUMBER(p) p자리의 수를 저장하며 소수 첫 번째자리에서 반올림합니다.
- NUMBER(p, 0)과 같습니다.
precision과 scale을 모두 명시하는 경우
- NUMBER(p, s) => p자리의 수를 저장하며 소수점 s자리까지 표현합니다.
- NUMBER(p, -s) => p자리의 수를 저장하며 (-s)의 자리에서 반올림합니다 (소수점 왼쪽에서 s자리까지 표현합니다.)
- 스케일은 음수값도 지정이 가능합니다. 음수를 지정하는 경우는 소수점의 왼쪽에서 처리가 됩니다.
- 예를 들면 NUMBER(5, -2)는 5자리의 전체 자릿수에 100의 자리에서 스케일 처리를 합니다.
NUMBER 데이터 눈으로 보는 예시
예시자료는 NUMBER(5, 2) 컬럼을 이용합니다. 전체 자릿수 5이며 소수점 둘 째자리까지 반올림하는 모습입니다. 아래는 테스트 참고 자료이니 참고하여 확인해 보세요~ 😉
DECLARE
n NUMBER := 123.4;
BEGIN
FOR i IN 1 .. 1000
LOOP
INSERT INTO TABLENAME
VALUES (n + i / 1000, n + i / 1000);
END LOOP;
COMMIT;
END;