LoginSignup
6
2

More than 5 years have passed since last update.

Oracle Data Pumpにおける予期しない文字コード変換

Last updated at Posted at 2017-06-22

はじめに

Oracle Data Pumpは論理バックアップおよび異なるバージョンやオペレーティング・システムのOracle Database間でデータを安全に転送できる優れたツールです。Oracle Database 10g以降の標準機能(圧縮機能や暗号化には別途追加ランセンスが必要)であり、従来の Export / Importユーティリティの機能を引き継いでいます。本資料では、Data Pumpユーティリティを使ったデータ移行時に予期せぬ文字コード変換が発生することを示しています。

文字コード(エンコード)の変換機能

Data Pumpはエンコードが異なるデータベース間で自動的に文字コードの変換を行います。変換処理はImport (impdp) 時に行われます。環境変数NLS_LANGには依存せず、自動的にインポート先のエンコードに変換されて格納されます。このためData Pumpにはエンコード関連を指定するパラメーターはありません。

問題となる文字

Microsoft Windows等で広く使われてきたShift_JISには様々な拡張が行われました。以下のような文字集合が拡張されています。

文字集合 コードポイント
NEC特殊文字 8740 - 879C
NEC選定IBM拡張文字 ED40 - EEFC
IBM拡張文字 FA40 - FC4B

上記のうち、例えば以下の文字は同一のグリフにもかかわらず、IBM拡張文字とNEC選定文字両方にコードが定義されています。

文字 IBM拡張文字 NEC拡張文字 Unicode
0xFA4A 0x8754 \u2160
0xFA4B 0x8755 \u2161
0xFA4C 0x8756 \u2162
0xFA4D 0x8757 \u2163
0xFA4E 0x8758 \u2164
0xFA4F 0x8759 \u2165
0xFA50 0x875A \u2166
0xFA51 0x875B \u2167
0xFA52 0x875C \u2168
0xFA53 0x875D \u2169
0xFA40 0xEEEF \u2170
0xFA41 0xEEF0 \u2171
0xFA42 0xEEF1 \u2172
0xFA43 0xEEF2 \u2173
0xFA44 0xEEF3 \u2174
0xFA45 0xEEF4 \u2175
0xFA46 0xEEF5 \u2176
0xFA47 0xEEF6 \u2177
0xFA48 0xEEF7 \u2178
0xFA49 0xEEF8 \u2179
0xFA59 0x8782 \u2116
0xFA58 0x878A \u3231
0xFAB1 0xED95 \uFA11
0xFBFC 0xEEE0 \u9AD9

文字コードJA16SJISから文字コードJA16SJISTILDEに移行

文字コードJA16SJISのデータベースと文字コードJA16SJISTILDEのデータベースを作成し、Data Pumpによるデータ移行を行います。この2つの文字コードは'~'の扱い以外は同一のコード体系を持っています。

両方の文字コードを格納

文字コードJA16SJISで作成されたデータベースに、NEC拡張文字とIBM拡張文字でラテン数字のⅠを格納します。見た目ではわかりませんが、DUMP関数で格納コードを確認すると正しく格納されています。

SQL> SELECT c1, DUMP(c1, 16) DMP FROM encode1 ;
C1                   DMP
-------------------- --------------------
Ⅰ                   Typ=1 Len=2: fa,4a      ← IBM拡張コード
Ⅰ                   Typ=1 Len=2: 87,54      ← NEC拡張コード

Data Pumpでデータ移行

次に Data Pumpユーティリティを使って、エンコードJA16SJISのデータベースからエンコードJA16SJISTILDEのデータベースへデータの移行を行ってみます。

# Export
$ export ORACLE_SID=sjis1
$ expdp SCOTT/pass DIRECTORY=DATA_PUMP_DIR DUMPFILE=encode1.dmp TABLES=encode1

# Import
$ export ORACLE_SID=tilde1
$ impdp SCOTT/pass DIRECTORY=DATA_PUMP_DIR DUMPFILE=encode1.dmp TABLES=encode1

格納文字コードを確認

文字コードを確認します。

SQL> SELECT C1, DUMP(c1, 16) DMP FROM encode1 ;

C1                   DMP
-------------------- --------------------
Ⅰ                   Typ=1 Len=2: 87,54
Ⅰ                   Typ=1 Len=2: 87,54

上記のように、NEC拡張文字のコードに変更されて格納されていることがわかります。
JA16SJISとJA16SJISTILDEのようにほとんど同一の文字コードの場合でも、Data Pump による移行では文字コード変換が行われ、意図しない文字コード変換が起こる可能性があります。

6
2
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
6
2