IT/ORACLE

EXPORT받은 DUMP 파일의 CHARACTER SET 확인 방법

Qhtlr 2007. 5. 31. 17:10

작년 중국에서의 ERP프로젝트때 Legacy System들이 US7ASCII에 중국어가 들어있어 ERP의 UTF8과의 연동에 문제가 있어 모든 Legacy System들의 캐릭터셋을 ZHS16GBK로 변경했었는데, 그때 Export파일의 캐리터셋 정보를 강제로 변환해서 import할때 필요한 정보였습니다.

다른 server에서 export받아온 dump file을 import시킬 경우 자주 겪게 되는
문제가 characterset에 관련된 것이다.
양쪽의 characterset이 같고 .profile의 환경변수(NLS_LANG)도 맞다고
생각되는 데도 import 시 segment fault가 발생되거나
imp-16, 36, 37, 38, 42, 43, 45, 49 등의 error가 발생되면 dump받아온 file
을 의심해볼 필요가 있다.

이 때 dump file을 8진수로 변환해 보면 현재 export받은 file의
characterset을 쉽게 알 수 있다.

오라클 export file은 특별한 character set을 사용해서 쓰여진다.
version 5, 6에서는 export 시 단지 두개의 character set-ASCII와 EBCIDC-만이
지원되었으나, version 7에서는 지원하는 모든 character set이 export 시에
사용될 수 있다. export 시 사용된 character set은 dump file 내에 code로써
기술되는데 file의 첫 byte가 이것을 나타낸다.

1st byte     의미
----------------------------------------------------
1               version 5, 6의 ASCII character set
2               version 5, 6의 EBCDIC character set
3               version 7의 character set.

"3"일 경우 두, 세번째 byte를 기준으로 character set을 판단한다.
아래에는 우리가 흔히 접하는 character set에 대한 character set ID이다.

2nd  3rd                 value
--------------------------------------------------
000  001   (1)           US7ASCII
000  002                 WE8DEC
000  037                 WE8ISO8859P1
003  110  ('H')         KO16KSC5601                              Hex : 0348
003  147  ('g')         UTF8 (oracle 8.0 이상부터 지원)     Hex : 0367
003  124  ('T')         ZHS16GBK                                  Hex : 0354
:                         :
:                         :

export file을 체크하기 위해서는 다음의 unix command를 사용한다.

$ od -b expdat.dmp|more

0000000 003 000 001 105 130 120 117 122 124 072 126 060 067 056 060 062
0000020 056 060 062 012 104 112 115 113 111 115 012 122 124 101 102 114
     :
     :
위의 경우 1st byte가 003이므로 version 7이며, 3rd byte가 001이므로 ID가
1번인 US7ASCII가 character set이 된다.

#od -b test.dmp|more
0000000  003 003 110 105 130 120 117 122 124 072 126 060 070 056 060 061    <- ko16ksc5601의 경우
0000020  056 060 067 012 104 123 131 123 124 105 115 012 122 124 101 102
0000040  114 105 123 012 064 060 071 066 012 060 012 062 070 012 060 012
0000060  003 110 003 110 003 110 000 001 000 000 000 000 000 000 000 000
0000100  000 010 000 040 040 040 040 040 040 040 040 040 040 040 040 040
0000120  040 040 040 040 040 040 040 040 040 040 040 040 040 040 040 040
0000140  040 040 040 040 040 040 040 040 040 124 150 165 040 115 141 171
0000160  040 063 061 040 061 067 072 063 072 061 065 040 062 060 060 067
0000200  164 145 163 164 056 144 155 160 000 000 000 000 000 000 000 000
0000220  000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000

select nls_charset_id(value) nls_charset_id,  value
from  v$nls_valid_values
where parameter = 'CHARACTERSET'
order by nls_charset_id(value);

Gives the nls_charset_id in DECIMAL, so you need to convert it to HEX first.