본문 바로가기

Oracle CHAR 타입에서 발생하는 공백 문제 해결하기

@cojoop 2025. 7. 8. 09:51

API 서버에 메시지 전송 정보를 저장하는 과정에서 오류가 발생했고,
로그를 분석해보니 DB에 저장된 문자열 끝에 의도치 않은 공백이 포함되어 있는 것이 원인이었다. 

 

간단해 보였던 문자열 저장이 Oracle의 CHAR 타입 특성 때문에 예상치 못한 문제로 이어진 것이다.

 

이번 글에서는 이 공백 이슈의 원인해결 방법을 정리해보려 한다.


💡문제 상황

메시지 전송 정보를 저장하는 tran_type 컬럼에 "TEXT"라는 문자열을 저장했다.
그런데 DB를 조회해보니, 예상과 달리 값이 다음과 같이 저장되어 있었다.

'TEXT                '

즉, "TEXT" 뒤에 공백(스페이스)이 자동으로 붙어 있었던 것이다.

이로 인해 다음과 같은 문제가 발생했다.

-- 작동하지 않음
SELECT * FROM MTS_BTALK_MSG WHERE TRAN_TYPE = 'TEXT';

→ 'TEXT     ''TEXT'서로 다른 문자열이기 때문에 조건에 걸리지 않는다.


🔍원인 분석: CHAR(n)의 고정 길이 특성

Oracle에서는 문자열 타입으로 CHAR(n) VARCHAR2(n) 두 가지 타입을 제공한다.
이 문제의 원인은 tran_type 컬럼이 CHAR(20)으로 선언되어 있었기 때문에 발생했다.

📌 CHAR(n)의 특성

  • 고정 길이 문자열 타입
  • 입력값이 n보다 짧으면, 공백으로 자동 패딩
  • ex. CHAR(20) 컬럼에 'TEXT'를 넣으면 → 'TEXT '로 저장됨 (20자)

📌 VARCHAR2(n)의 특성

  • 가변 길이 문자열 타입
  • 입력한 그대로 저장됨
  • 공백이 자동으로 붙지 않음

📉 CHAR 사용 시 발생 가능한 문제

1. 조건 검색 오류

CHAR(20) 컬럼에 'TEXT'를 넣었을 경우, 실제 저장은 'TEXT       '가 되기 때문에
다음과 같은 조건 검색은 실패할 수 있다.

-- 실패할 수 있음
SELECT * FROM MTS_BTALK_MSG WHERE TRAN_TYPE = 'TEXT';

→ 'TEXT''TEXT   '는 동일하지 않음

2. JSON 직렬화 시 데이터 이상

Java 객체를 JSON으로 변환할 때도 "TEXT    "처럼 공백이 포함된 상태로 직렬화되어
프론트엔드에서 문자열 비교나 분기 처리 시 오작동 가능성이 생긴다.

3. UI 렌더링 오류

공백이 포함된 문자열이 그대로 화면에 출력되면
버튼 너비가 깨지거나 텍스트 정렬이 틀어지는 등 시각적 문제가 발생할 수 있다.


✅ 해결 방법

📌 방법 1. CHAR → VARCHAR2로 타입 변경

DB 컬럼을 다음과 같이 변경한다.

ALTER TABLE TABLE_NAME MODIFY TRAN_TYPE VARCHAR2(20);
  • 이렇게 하면 'TEXT'를 넣었을 때 그대로 저장됩니다
  • 모든 문자열 필드에는 기본적으로 VARCHAR2를 사용하는 것이 Oracle에서의 표준 실무입니다

📌 방법 2. TRIM으로 공백 제거

DB 구조를 바로 바꾸기 어려운 경우, 코드나 SQL 쿼리에서 TRIM 처리를 통해 공백을 제거할 수 있다.

 

Java 코드

String type = resultSet.getString("TRAN_TYPE").trim();

MyBatis SQL

<select id="getType" resultType="String">
  SELECT TRIM(TRAN_TYPE) FROM TABLE_NAME
</select>
단점: 모든 비교, 조회, 직렬화 과정에 TRIM을 반복 적용해야 하므로 유지보수가 불편하다.

❓왜 CHAR은 잘 안 쓸까?

구분  CHAR  VARCHAR2
저장 방식 고정 길이 가변 길이
남은 공간 처리 공백으로 자동 패딩 없음
문자열 비교 공백 주의 필요 일반 문자열처럼 비교 가능
실무 활용도 거의 없음 매우 높음
  • CHAR는 문자열 정렬이 필요한 특수 상황 외에는 거의 사용되지 않음
  • VARCHAR2가 Oracle에서 사실상의 표준 문자열 타입

 

마무리

이번 경험을 통해 CHAR과 VARCHAR2는 단순한 타입 차이가 아니라, 동작 방식과 저장 결과 자체가 완전히 다르다는 점을 알게 되었다.

 

앞으로는 문자열 컬럼은 무조건 VARCHAR2를 기본으로 사용하고, CHAR은 가능한 한 사용하지 않으려 한다.

 

그리고 레거시 시스템에서 CHAR이 남아 있다면, 반드시 그 컬럼들을 점검하고, 공백으로 인해 발생할 수 있는
조회 오류, UI 깨짐, JSON 직렬화 문제 등을 사전에 방지해야 할 것이다.

'Database > Oracle' 카테고리의 다른 글

DB 링크(Database Link)란?  (2) 2025.06.27
cojoop
@cojoop :: cojoop.dev

공감하셨다면 ❤️ 구독도 환영합니다! 🤗

목차