HHeLiBeXの日記 正道編

日々の記憶の記録とメモ‥

IMPORTとLOADとcodepageの指定

データをデータベースにインポート/ロードする際には、コードページの指定は当然だと思っているが、コードページを指定していないスクリプトファイルに出くわしたことがきっかけで、ちょっと調べてみようと思った。
ちなみに、DB2 v9.5からLOADコマンドでXMLデータがロードできるようになってから、私はLOAD派。ロードするデータが正しければ、各種制約を考慮してロードの順番を気にするということが必要ないから。何より大量データをロードする際にIMPORTコマンドより高速だし。

環境

使用した環境をざっくりと。

実験の概要

  • VARCHAR型およびXML型のデータをロードする
  • UTF-8Shift_JISEUC-JPのそれぞれで保存されたデータを用意する
  • IMPORTおよびLOADコマンドでデータをロードする
    • codepage指定なし
    • codepage=1208を指定
    • codepage=932を指定
    • codepage=954を指定

データベースと表の作成

以下のSQL文を実行。

CREATE DATABASE DB_1208 USING CODESET UTF-8 TERRITORY JP COLLATE USING SYSTEM PAGESIZE 32 K ;
CONNECT TO DB_1208 USER db2admin USING db2admin ;

-- "codepage指定なし"のための表 --
CREATE TABLE TBL_NOSP_1208(OP VARCHAR(16) NOT NULL, VAL1 VARCHAR(32), VAL2 XML, PRIMARY KEY(OP)) ;
CREATE TABLE TBL_NOSP__932(OP VARCHAR(16) NOT NULL, VAL1 VARCHAR(32), VAL2 XML, PRIMARY KEY(OP)) ;
CREATE TABLE TBL_NOSP__954(OP VARCHAR(16) NOT NULL, VAL1 VARCHAR(32), VAL2 XML, PRIMARY KEY(OP)) ;
-- "codepage=1208 を指定"のための表 --
CREATE TABLE TBL_1208_1208(OP VARCHAR(16) NOT NULL, VAL1 VARCHAR(32), VAL2 XML, PRIMARY KEY(OP)) ;
CREATE TABLE TBL_1208__932(OP VARCHAR(16) NOT NULL, VAL1 VARCHAR(32), VAL2 XML, PRIMARY KEY(OP)) ;
CREATE TABLE TBL_1208__954(OP VARCHAR(16) NOT NULL, VAL1 VARCHAR(32), VAL2 XML, PRIMARY KEY(OP)) ;
-- "codepage=932 を指定"のための表 --
CREATE TABLE TBL__932_1208(OP VARCHAR(16) NOT NULL, VAL1 VARCHAR(32), VAL2 XML, PRIMARY KEY(OP)) ;
CREATE TABLE TBL__932__932(OP VARCHAR(16) NOT NULL, VAL1 VARCHAR(32), VAL2 XML, PRIMARY KEY(OP)) ;
CREATE TABLE TBL__932__954(OP VARCHAR(16) NOT NULL, VAL1 VARCHAR(32), VAL2 XML, PRIMARY KEY(OP)) ;
-- "codepage=954 を指定"のための表 --
CREATE TABLE TBL__954_1208(OP VARCHAR(16) NOT NULL, VAL1 VARCHAR(32), VAL2 XML, PRIMARY KEY(OP)) ;
CREATE TABLE TBL__954__932(OP VARCHAR(16) NOT NULL, VAL1 VARCHAR(32), VAL2 XML, PRIMARY KEY(OP)) ;
CREATE TABLE TBL__954__954(OP VARCHAR(16) NOT NULL, VAL1 VARCHAR(32), VAL2 XML, PRIMARY KEY(OP)) ;

データベースのコードセットは、XML型を使用する関係でUTF-8
表の名前は、「TBL_<指定するcodepage>_<データのcodepage>」の形式。

使用するデータ

ロード用DELファイル(IMPORT用)(文字エンコーディングが違うだけで内容はUTF-8Shift_JISEUC-JP共通)

"IMPORT_1208","あいうえお",<XDS fil='data.1208.xml' />
"IMPORT__932","あいうえお",<XDS fil='data.932.xml' />
"IMPORT__954","あいうえお",<XDS fil='data.954.xml' />

ロード用DELファイル(LOAD用)(文字エンコーディングが違うだけで内容はUTF-8Shift_JISEUC-JP共通)

"LOAD_1208","あいうえお",<XDS fil='data.1208.xml' />
"LOAD__932","あいうえお",<XDS fil='data.932.xml' />
"LOAD__954","あいうえお",<XDS fil='data.954.xml' />

XMLデータ"data.1208.xml"(UTF-8)(IMPORT、LOADで共通)

<?xml version='1.0' encoding='UTF-8'?>
<data>あいうえお</data>

XMLデータ"data.932.xml"(Shift_JIS)(IMPORT、LOADで共通)

<?xml version='1.0' encoding='Shift_JIS'?>
<data>あいうえお</data>

XMLデータ"data.954.xml"(EUC-JP)(IMPORT、LOADで共通)

<?xml version='1.0' encoding='EUC-JP'?>
<data>あいうえお</data>

IMPORTおよびLOAD

-- codepage指定なし --
IMPORT FROM "data.import.1208.del" OF DEL                           INSERT INTO TBL_NOSP_1208 ;
LOAD   FROM "data.load.1208.del"   OF DEL                           INSERT INTO TBL_NOSP_1208 ;
IMPORT FROM "data.import.932.del"  OF DEL                           INSERT INTO TBL_NOSP__932 ;
LOAD   FROM "data.load.932.del"    OF DEL                           INSERT INTO TBL_NOSP__932 ;
IMPORT FROM "data.import.954.del"  OF DEL                           INSERT INTO TBL_NOSP__954 ;
LOAD   FROM "data.load.954.del"    OF DEL                           INSERT INTO TBL_NOSP__954 ;
-- codepage=1208 を指定 --
IMPORT FROM "data.import.1208.del" OF DEL MODIFIED BY CODEPAGE=1208 INSERT INTO TBL_1208_1208 ;
LOAD   FROM "data.load.1208.del"   OF DEL MODIFIED BY CODEPAGE=1208 INSERT INTO TBL_1208_1208 ;
IMPORT FROM "data.import.932.del"  OF DEL MODIFIED BY CODEPAGE=1208 INSERT INTO TBL_1208__932 ;
LOAD   FROM "data.load.932.del"    OF DEL MODIFIED BY CODEPAGE=1208 INSERT INTO TBL_1208__932 ;
IMPORT FROM "data.import.954.del"  OF DEL MODIFIED BY CODEPAGE=1208 INSERT INTO TBL_1208__954 ;
LOAD   FROM "data.load.954.del"    OF DEL MODIFIED BY CODEPAGE=1208 INSERT INTO TBL_1208__954 ;
-- codepage=932 を指定 --
IMPORT FROM "data.import.1208.del" OF DEL MODIFIED BY CODEPAGE=932  INSERT INTO TBL__932_1208 ;
LOAD   FROM "data.load.1208.del"   OF DEL MODIFIED BY CODEPAGE=932  INSERT INTO TBL__932_1208 ;
IMPORT FROM "data.import.932.del"  OF DEL MODIFIED BY CODEPAGE=932  INSERT INTO TBL__932__932 ;
LOAD   FROM "data.load.932.del"    OF DEL MODIFIED BY CODEPAGE=932  INSERT INTO TBL__932__932 ;
IMPORT FROM "data.import.954.del"  OF DEL MODIFIED BY CODEPAGE=932  INSERT INTO TBL__932__954 ;
LOAD   FROM "data.load.954.del"    OF DEL MODIFIED BY CODEPAGE=932  INSERT INTO TBL__932__954 ;
-- codepage=954 を指定 --
IMPORT FROM "data.import.1208.del" OF DEL MODIFIED BY CODEPAGE=954  INSERT INTO TBL__954_1208 ;
LOAD   FROM "data.load.1208.del"   OF DEL MODIFIED BY CODEPAGE=954  INSERT INTO TBL__954_1208 ;
IMPORT FROM "data.import.932.del"  OF DEL MODIFIED BY CODEPAGE=954  INSERT INTO TBL__954__932 ;
LOAD   FROM "data.load.932.del"    OF DEL MODIFIED BY CODEPAGE=954  INSERT INTO TBL__954__932 ;
IMPORT FROM "data.import.954.del"  OF DEL MODIFIED BY CODEPAGE=954  INSERT INTO TBL__954__954 ;
LOAD   FROM "data.load.954.del"    OF DEL MODIFIED BY CODEPAGE=954  INSERT INTO TBL__954__954 ;

表の中身を出力

文字化けを含むので、ファイルに保存したものをテキストエディタで開いてスクリーンショットを取ったもの。
codepage指定なし

codepage=1208を指定

codepage=932を指定

codepage=954を指定

指定したコードページとデータ(DELファイル)のコードページが合っていないものは当然文字化け。
注目するのは、コードページを指定しなかった場合。この結果から、IMPORTコマンドはOSのデフォルトコードページ(?)、LOADコマンドはデータベースのコードページが使用されていそうだということが推測できる。
また、XMLデータは、指定したコードページに関係なく、XML宣言での指定に従って処理されている(ようだ)。

(2009/05/24追記)
EUC-JP(codepage=954)も追加した。これで、OSのデフォルトエンコーディングと異なる文字エンコーディングで保存されたデータをロードするには、codepageを指定しなければならないことが説明できると思う。
ちなみに、DB2 Enterprise Server Edition(ESE) v9.5の環境で試す機会があったので確認してみたが、FP1では結果が違っていた。主な違いは以下のとおり。

  • codepage指定なしのケースでは、IMPORT、LOADともに、UTF-8のデータは文字化け、Shift_JISのデータは正常に見えた。
  • codepageを指定した場合の動作はよく覚えていない(ぉ
  • XMLデータも文字化けして表示された。

XMLデータの出力まで文字化けして見えたのが、コマンド・ウィンドウ(db2コマンド)の問題なのか、IMPORT/LOADの問題なのかは不明。JDBCドライバ経由でデータを取得するプログラムを組んでみればきちんと確認できたのかも。FP2を適用すると、Express-C(v9.5.2)で確認したのと同じ結果になった。