작년 중국에서의 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.