IT/Oracle

Oracle UTF8 - US7ASCII 케릭터셋 연동 (오라클 데이터 인터페이스)

귀차니즘 극복 2020. 3. 23. 16:47
728x90
반응형

아직도 지금 다니고 있는 회사에서는 US7ASCII 케릭터셋을 많이 사용하고 있다.

 

아무래도 초기 데이터 베이스를 구축할 때 기본 설치 및 세팅이 US7ASCII로 되어서 데이터가 축적되고 있다보니,

그 부분에 대한 전환을 별도하지 않고 계속적으로 사용되는 것 같다.

 

하지만 요즈음 예전과 다르게 다국어 지원도 가능해야 하며, 기존에 사용하지 않던 한글들이 생겨나 많이 사용되고 있다.

 

예전처럼 US7ASCII로 한글을 억지로 사용하는 것은 지양되고 있으며, 신규 시스템들은 UTF8로 많이 구축 되고 있다.

 

하지만 이렇게 케릭터셋이 다른 DB를 동시에 운영하고, 두 데이터베이스간 데이터를 인터페이스 해야 할 경우에 어떻게 할 것인지 고민해봐야 한다.

 

 

 

이제 실제 상황에서 활용하는 것을 보면,

 

"

A라는 시스템이 신규 구축 되었다.

 

이 시스템의 Oracle DB 캐릭터셋은 UTF8이다.

 

헌데 A라는 시스템의 데이터를 B라는 시스템에 연동해야 한다.

 

B라는 시스템의 Oracle DB 캐릭터셋은 US7ASCII이다.

 

여기의 Batch 관리는 Java로 구성되어 있지 않으며, 기존 Batch프로그램을 간단하게 수정하여 처리하고 싶다.

 

Source 시스템에 view를 만들고, 이를 가져가서 Target 시스템에 넣으려고 한다.

"

 

 

그래서 구글링을 통해 검색한 방법은?

 

"
US7ASCII로 된 데이터베이스에서 VIEW를 통해 원하는 컬럼을 RAW 형식으로 바꾼 다음에 이를 목적지 데이터베이스에서는 역 컨버전 함수를 사용해서 가져오면 된다.

소스에서는
  CREATE VIEW VIEW_TORAW AS
  SELECT UTL_RAW.CAST_TO_RAW('테스트') AS RAW_COL FROM DUAL

타겟에서는
  SELECT UTL_RAW.CAST_TO_VARCHAR2(RAW_COL) FROM VIEW_TORAW

"

 

오,,, 왠지 그럴싸해 보인다.

 

이진으로 저장되니 이를 RAW로 변경하고 이를 가져다가 변경하면 될 것 같다.

 

결과는??

 

-----------------------실패...............(이러면 굳이 이걸 안써도 되었겠지?)

 

 

 

 

그래서 이번엔 그런 경험이 많은 담당자들에게 물어본다.

 

그래서 나온 방법!!!!!!!!!

 

 

"

/* Source UTF8 DB에서 View 생성 */

- UTL_RAW.CAST_TO_RAW(CONVERT('컬럼명', 'KO16KSC5601', 'UTF8'));

 

/* Target US7ASCII DB에서 SELECT*/

- UTL_RAW.CAST_TO_VARCHAR2('가져온값');

"

 

위 해결방법과 비슷한데 CONVERT함수를 추가적으로 사용했다.

 

CONVERT함수는 문자세트를 다른 문자세트로 문자열을 변환한다.

반환되는 데이터형은 VARCHAR2이다.

 

 

앞에가 변환될 케릭터셋, 뒤에가 원래 케릭터셋이다.

 

CONVERT('컬럼명', 'KO16KSC5601', 'UTF8')는 "UTF8 → KO16KSC5601"로 바꾸겠다는 내용이다.

 

 

그럼 왜 이렇게 해야 제대로 되는 것인지 한번 알아 볼 필요가 있다.

 

그러기 위해서는 먼저,

 

US7ASCII는 어떻게 한글을 저장하는지 살펴 볼 필요가 있다.

 

 

이리 저리 검색을 많이 해 본 결과 아래 내역이 가장 이해가 잘 되는 내역인 것 같다.

 

"

US7ASCII는 영문 케릭터셋으로 한글을 저장할 수 없는 케릭터셋인데,

한글 데이터를 저장하고 관리한 시스템이 존재한다.

캐릭터셋은 US7ASCII지만, 실제로 "완성형 + 한글 윈도우즈 코드" 페이지(KO16MSWIN949)의 데이터를 저장해 온 경우

데이터는 현재 상태에서 가공하지 않은 채, 딕셔너리에 있는 캐릭터셋 정보만을 강제로 KO16MSWIN949로 변환하는 방식으로 활용 할 수 있다.

US7ASCII 데이터베이스에 한글을 저장하게 될 경우, 한 글자당 2바이트로 저장된다.  
일반적으로 사용하는 클라이언트는 대부분 Windows-949(한글 Windows OS)나 KSC5601 완성형(UNIX계열)이고

이들은 모두 2바이트이다.

"

 

 

요약해보자면,

US7ASCII는 원래 한글을 저장하는 케릭터셋은 아니지만,

한글 완성형으로 가공하지 않은(이진) 상태로 데이터 저장하고, 이를 딕셔너리 캐릭터셋 정보로 조회하면 한글을 쓰고 조회할 수 있다는 이야기다.

 

그리고 완성형 한글을 기준으로 하기에 2바이트 사용으로 데이터를 차지한다는 것으로 보인다.

 

 

US7ASCII는 기본적으로 클라이언트 환경에 좌지우지되며,

이는 대부분 완성형 한글이기 때문에 KO16MSWIN949나 KO16KSC5601와 동일하게 처리된다고 볼 수 있다.

 

 

뭐 주절주절 이야기가 많았지만 요약해서 정리를 하자면,

 

"

UTF8 → US7ASCII로 변환하기 위해서는 바로 UTL_RAW.CAST_TO_RAW로 변경해서는 한글이 깨지며,

US7ASCII의 한글이 완성형으로 저장되니 이와 호환되는 KO16KSC5601로 CONVERT한 후 처리하면 위와 같은 방법으로 기존의 Batch를 수정하여 쉽게 구성 할 수 있다.

"

 

 

물론 위와 같은 방식도 문제가 전혀 없는 것은 아니다.

 

일반적으로 한글을 표현하는 케이스가 더 많은 부분으로 전환되는 것은 맞지만, UTF8 한글을 US7ASCII로 전환하기에는 한계가 있다. (ex. 쁧/뷣/톩/똠 등)


US7ASCII < KO16KSC5601 < KO16MSWIN949 < UTF8 < AL32UTF8

 

반대로 캐릭터셋을 바꾸면 문자 소실이 발생할 수 있음을 유의하고, 정상적인 한글을 위주로 사용한다면 한글이 깨지는 경우는 거의 없을 듯 하다.

 

 

그리고 아래는 개발사에서 진행한 부분인데 아래 부분도 추가적으로 적용해보면 좋을 듯 하다.

 

 

"

UTF8 DB에서 View 생성

  - UTL_ENCODE.TEXT_ENCODE(컬럼, 'K016KSC5601', 1);

 

US7ASCII DB에서 SELECT

  - UTL_ENCODE.TEXT_DECODE(가져온값,'US7ASCII',1);

"

 

 

 

도움이 되셨다면~

 

공감과 댓글 부탁드립니다!

728x90
반응형