[MySQL + Express] DECIMAL 타입이 STRING으로 나오는 상황

아이엠강욱·2023년 6월 17일
0

트러블슈팅

목록 보기
1/4

문제 상황

어제 동아리에서 연계해준 외주를 진행하면서 다른 백엔드 분이 뭘 잘못 작업하셨는지 한 클라분이 나한테 포인트 관련 값들을 실수로 반환하게 해달라고 요청이 와서 작업을 시작했다.

컬럼 타입을 보니 요청하신 데이터 타입이 전부 INT였어서 DECIMAL(20, 2)로 변경을 했다.
(소수 두자리까지 허용해달라는 기획자분의 요청)

그런데 DECIMAL로 변경하니까 Response로 나오는 값들이 전부 String으로 변경이 되는 것이다.

point: 20 -> point: "20.2"

이런식으로 반환이 되는 것이다.

해결 방법

그래서 이거를 수정해야 할 부분마다 parseFloat을 적용해야 하나 했다가 처음으로 ChatGPT의 도움을 받아봤다. 2가지의 방법을 제시해주었다.

1. CAST 함수 사용

SELECT CAST(your_column AS DECIMAL(10,2)) AS your_column_numeric FROM your_table;

CAST 함수를 써서 형변환을 시켜주면 정상적으로 나온다.
이 방법을 사용할까 하다가.. 그러면 필요한 쿼리문에 전부 CAST를 적용시켜야해서 번거로울 것 같았다.

2. MySQL 연결 설정부분 코드 변경

const mysql = require('mysql');

const connection = mysql.createConnection({
  host: 'your_host',
  user: 'your_user',
  password: 'your_password',
  database: 'your_database',
  typeCast: function (field, next) {
    if (field.type === 'NEWDECIMAL') {
      return parseFloat(field.string());
    }
    return next();
  },
});

위의 코드는 mysql에 연결할 때 작성하는 Config 코드이다. 위의 코드는 MySQL 드라이버에 따라 차이가 있을 수 있기 때문에 사용하는 드라이버에 따라 해당 설정을 찾아야 한다.

typeCast을 추가 적용하면서 쉽게 해결할 수 있었다. Type이 DECIMAL인 것은 parseFloat 처리를 해주는 것이다.

왜 String으로 반환될까?

해결은 했지만 도대체 왜 string으로 반환될까를 진짜 오래 생각해봤다. int는 숫자로 잘 반환하면서 왜 decimal은 안되는거지?

찾아보니까 MySQL의 내부 동작과 데이터 유형에 관련이 있다고 한다.

MySQL은 Decimal 데이터를 정확한 숫자로 저장하기 위해서 내부적으로 문자열로 처리한다고 한다.
부동 소수점 연산의 부정확성을 피하고 정확한 숫자 값을 보장하기 위한 방식이라고 한다.
그래서 Decimal 값을 SELECT 할 때 문자열로 반환하는 것이다.

느낀점

구글링으로 계속 찾아보다가 자료가 잘 안나와서 처음으로 ChatGPT를 써봤는데 생각보다 되게 유용한 것 같다...?
ChatGPT 감사합니다..ㅎㅎ 덕분에 해결했습니다 :)

profile
블로그 이전했습니다!! https://dev-iamkanguk.tistory.com/ <<- 여기로 오세용!!

0개의 댓글