1 minute read

오잉? 분명히 값이 있는데 값이 없다고 나온다고??

2년전 만들었던 적재 모듈에서 에러가 발생하였다. 분명 2년동안 문제가 없었던 모듈이였는데???

형상관리의 실패였다. 배포 버전보다 이전버전의 작업물을 가지고 하다보니, 문제가 발생하였다. 이런,,,

문제는 오라클에서 마리아로 마이그레이션 및 ETL 작업중에 발생한 문제였다.

ISSUE. NN -> .NN 문제

일단 내 자바 프로젝트 내에서 의심할 케이스는 두가지!.

  • 1번케이스: ORACLE 에서 TO_CHAR 를 통해 숫자 값을 문자로 변환할때
  • 2번케이스: ORACLE 에서 값이 0.NN 과 같은 숫자형이고 Java 객체 타입이 String 일때 Mybatis 가 형변환을 해주며 발생한 문제

뭐,, 둘다 똑같은 문제 이다 결국 숫자를 문자로 변환할때 발생하는 문제라는 것이다.

확인을 해보자

문제 예시

TEST 데이터 생성

CREATE TABLE TEST
(
VALUE     NUMBER(35,10)
);

INSERT INTO TEST 
VALUE 
VALUES
(0.987);

SELECT * FROM TEST 결과

0.987

SELECT TO_CHAR(VALUE) FROM TEST 결과

.987

해결방법

찾아보면 TO_CHAR 에 FORMAT 을 사용 하면 된다고 나온다. 하지만 이게 십진수, 소수점 의 자릿수들이 값마다 다르므로 완벽히 decimal 값을 가져오는건 조금 힘들수 있다.

그래서 이 format을 응용하여 아래와 같이 값을 사용하면 된다.

그전에 오라클의 NUMBER 형에 대해 다시 한번 짚어 보고 가자

NUMBER (p,s)
- p(precision, 정밀도): 최대 유효숫자 자리수를 나타낸다.
- s(scale): 소수점 기준 자릿수 

세부 설명
1. p는 소수점 기준 모든 유효숫자 자리수를 의미한다, 만약 p에 명시한 것보다 큰 숫자값을 입력하면 오류 발생
2. s가 양수면 소수점 이하, 음수이면 소수점 이상(소수점 기준 왼쪽) 유효숫자 자릿수를 나타냄
3. s가 명시한 숫자 이상의 숫자를 입력하면, s에 명시한 숫자로 반올림 처리
4. s가 음수이면 소수점 기준 왼쪽 자리수 만큼 반올림
5. s가 p보다 크면 p는 소수점 이하 유효숫자 자리수를 의미

이제 개념을 알았으니, TEST Table 의 NUMBER(35,10) 값을 처리해보자,

SELECT rtrim(to_char(VALUE, 'FM9999999999999999999999990.9999999999'), '.') AS VALUE  FROM TEST

차라리 코드단에서 처리하는게 좋을듯 하다…

해결책2 (권장)

Migration의 경우 Oracle 쪽의 경우 Double 형을 사용하고, 받는 쪽에서 String 값을 사용하거나 코드단에서 케스팅을 한다.

해결책3 (비권장)

Mybatis의 경우 Setter를 사용하여 값을 저장하므로, Setter에서 조건 처리를 한다. 비용도 많이 들고, 유지보수성에서 완전 구릴듯,,

어떤 부분을 내가 수정 가능하냐에 따르겠지만 나는 2번을 권장 한다.

아무튼 ,, 이런실수는 이제 그만

Categories:

Updated: