文字化けに関するトラブルに強くなる【基礎編】
・Oracleにおける文字コードの扱い
データベースキャラクタセット
NLS_LANG
文字コード変換
・文字化けの原因と対処
文字化けの典型的な発生パターン
(関連キーワード:データベースキャラクタセット、NLS_LANG、文字化け、Unicode、シフトJIS、日本語EUC)
データ格納における文字化け
クライアントのNLS_LANGのキャラクタセットとOracle Databaseのデータベースキャラクタセットが異なる場合に実行されるOracle内部の文字コード変換処理において、クライアント側で入力された文字が、データベース側のキャラクタセットでは対応していない場合に発生する文字化けのパターンです。
先に説明したとおり、NLS_LANGのキャラクタセットとデータベースキャラクタセットの値が異なる場合、クライアントからデータを格納するとき、クライアント側で文字コード変換が発生します。この処理は、図4の@の処理に相当します。NLS_LANGのキャラクタセットの対応文字種に含まれているが、データベースキャラクタセットの対応文字種に含まれない一部の文字については、文字コード変換が正常に実行できません。
典型的な例としては、データベースキャラクタセットJA16EUCのデータベースに対して、シフトJISの「
」(まるいち)などの「丸囲み文字」を格納する場合があります。
この文字はいわゆる「NEC特殊文字」と呼ばれる種類の文字で、Windows環境のシフトJISで利用可能であり、OracleにおいてもJA16SJISキャラクタセットで対応していますが、JA16EUCキャラクタセットでは対応していません。このため、Windows環境などのクライアントにおけるNLS_LANGのキャラクタセットがJA16SJISである環境から、データベースキャラクタセットがJA16EUCであるOracle Databaseに対して文字「
」を格納しようとすると、文字化けが発生します。
| キャラクタセット | 対応文字種(抜粋) |
|---|---|
| JA16SJIS JA16SJISTILDE |
ASCII JIS X 0208(JIS第1・第2水準漢字) 半角カナ(JIS X 0201のカタカナ) NEC 特殊文字(PC-98文字) NEC 選定IBM 拡張文字 IBM 拡張文字 ユーザー定義の外字 |
| JA16EUC JA16EUCTILDE |
ASCII JIS X 0208(JIS第1・第2水準漢字) 半角カナ(JIS X 0201のカタカナ) JIS X 0112補助漢字 |
| AL16UTF8 | Unicode※ |
実際に「
」(まるいち)文字を、NLS_LANGキャラクタセットJA16SJISであるクライアントからデータベースキャラクタセットJA16EUCのデータベースに格納してみましょう。
SQL> select * from V$NLS_PARAMETERS where PARAMETER like '%CHARACTERSET%'; PARAMETER VALUE ------------------------------ -------------------- NLS_CHARACTERSET JA16EUC (A) SQL> create table tbl1 (pk number(8) primary key , val varchar2(10)); SQL> insert into tbl1 values(1,'あ'); SQL> insert into tbl1 values(2,'');(B) SQL> commit; SQL> col DUMP16 format a60 SQL> select pk, val, dump(val, 16) DUMP16 from tbl1; PK VAL DUMP16 ---------- -------------------- ---------------------------------------------- 1 あ Typ=1 Len=2: a4,a2 2 ? Typ=1 Len=2: a1,a9 (C)
リスト2の(A)では、データベースキャラクタセットがJA16EUCであることを確認しています。(B)では、「
」(まるいち)文字をINSERTしています。(C)では、INSERTしたデータと、データの内部格納状態を確認しています。
DUMP()は、データベースに格納されたデータの内部状態を表示するための関数です。DUMP()の詳細はマニュアル「SQLリファレンス」を確認してください。ここでは、引数に「16」を指定して、内部表現を16進数で出力しています。
リスト2(B)でINSERTしたPK=2の行の確認結果を見ると、VAL列には、正しく「
」(まるいち)文字が表示されていません。また、DUMP()の結果から、文字が16進数で0xA1、0xA9で格納されていることが分かります。16進数の0xA1、0xA9は、「?」文字の日本語EUCでの内部表現に相当します。
実際に、「?」をINSERTしてDUMP()の結果を確認してみると、確かに16進数の0xA1、0xA9となっていることが分かります(リスト3(D))。
リスト3 「?」をINSERTした場合と比較SQL> insert into tbl1 values(3,'?');
SQL> commit;
SQL> select pk, val, dump(val, 16) DUMP16 from tbl1;
PK VAL DUMP16
---------- -------------------- -------------------------------------------
1 あ Typ=1 Len=2: a4,a2
2 ? Typ=1 Len=2: a1,a9
3 ? Typ=1 Len=2: a1,a9 (D)
クライアントで設定したNLS_LANGのキャラクタセットの対応文字種には含まれるが、データベースキャラクタセットの対応文字種に含まれない一部の文字については、文字コードの変換が正常にできないため、Oracleにより強制的に「?」文字に変換されてしまうことがお分かりいただけたでしょうか。このように、Oracleにおける文字コード変換の際に対応する文字がない場合、特定の文字に変換されます。
なお、このような状態になった場合、元の文字を復元することはできません。それは、データベースでは元の文字の情報が失われ、すでに「?」文字しか存在していないためです。このような問題を回避するためには、以下のアプローチが考えられます。
- システムの対応範囲外とする
上記の「
」のような、キャラクタセットによって対応/非対応が分かれる文字については、システムの対応範囲外とする。例えば、データベースキャラクタセットJA16SJISのデータベースに、NLS_LANGのキャラクタセットがJA16EUCのクライアントが接続する環境では、システムの対応文字種をASCII、JIS X 0208-1997 (JIS第1・第2水準漢字)、半角仮名(JIS X 0201-1997の片仮名)に限定する - すべてのキャラクタセットを限定する
すべてのクライアントのNLS_LANGのキャラクタセット、データベースキャラクタセットを、「
」をサポートするキャラクタセットに限定する。例えば、今回のケースでは、すべてのクライアントのNLS_LANGのキャラクタセットとデータベースキャラクタセットをJA16SJIS、JA16SJISTILDEといったシフトJIS系のキャラクタセット、Unicode系のキャラクタセットに限定する - すべてのキャラクタセットを統一する
文字コード変換が発生しないように、すべてのクライアントのNLS_LANG、データベースキャラクタセットを統一する - Unicodeとしてデータを格納する
Unicodeデータ格納用のデータ型(NCHAR型、NVARCHAR2型)のカラムにUnicodeとして格納する
データ取得における文字化け
データ取得においても、クライアントのNLS_LANGのキャラクタセットとデータベースキャラクタセットの値が異なる場合はクライアント側で文字コード変換が発生するため、格納の場合と同じメカニズムで文字化けが発生します。この処理は、図1(2)の処理に相当します。対処についてもデータ格納の対処策と同様の対処が考えられます。
データ表示における文字化け
Oracleレベルではデータが正常に取得できているが、OS/アプリケーション側で、文字データを表示する処理に問題があり発生する文字化けのパターンです。
図6 データ表示における文字化け
Oracleは、NLS_LANGに指定したキャラクタセットに対応した文字コードを、アプリケーションが適切に処理できると仮定します。いい換えれば、Oracleは、OS/アプリケーションが実際にその文字コードを適切に処理できるかどうかは特に考慮せず、OS/アプリケーションにNLS_LANGのキャラクタセットの文字コードでデータを出力します。なお、入力の際も同様です。
このため、OS/アプリケーションが実際には処理できない文字コードをNLS_LANGのキャラクタセットに指定すると、Oracleが入出力する文字データをOS/アプリケーションが処理できないため、文字化けが発生する場合があります。例えば、Windowsのコマンドプロンプト上で動作するSQL*Plus(sqlplus.exe)は、日本語EUCを適切に処理できません。従って、NLS_LANGにJA16EUCを指定すると、文字化けが発生します。
リスト4 Windows環境/SQL*PlusでJA16EUCを指定した場合C:\> set NLS_LANG=Japanese_Japan.JA16EUC
C:\> sqlplus test/test
SQL*Plus: Release 10.2.0.3.0 - Production on イミ 7キ・8 12:46:24 2008
Copyright (c) 1982, 2006, Oracle. All Rights Reserved.
Oracle Database 10g Enterprise Edition Release 10.2.0.3.0 - Production
With the Partitioning and Data Mining options
、ヒタワツウ、オ、・゙、キ、ソ。」
SQL>
SQL> col DUMP16 format a60
SQL> select pk, val, dump(val, 16) DUMP16 from tbl1;
PK VAL DUMP16
---------- ------------------------------ ------------------------------------
1 、「 Typ=1 Len=3: e3,81,82
2 。ゥ Typ=1 Len=3: e2,91,a0
9 ?? Typ=1 Len=2: 3f,3f
3 。ゥ Typ=1 Len=4: f0,a0,80,8b
8 。ゥ Typ=1 Len=4: f0,a0,80,8b
同様に、端末エミュレータ(TeraTerm、Putty、Gnome Terminalなど)でSQL*Plusを実行して、端末エミュレータの文字コード設定を日本語EUCとしたときに、NLS_LANGにJA16SJISを設定すると文字化けが発生します。
このような問題を回避するためには、以下のアプローチが考えられます。
- NLS_LANGのキャラクタセットをOS/アプリケーションが対応している文字コードに設定する
- OS/アプリケーションに文字コード設定が存在する場合は、それらをNLS_LANGのキャラクタセットに統一する
以上で、Oracleの文字化けについて基礎的な説明を終了します。
最後に
次回は本稿の内容を踏まえて、「〜(チルダ)」の文字化けに代表されるJavaなどのUnicodeベースのアプリケーションで発生する問題と、Windows Vistaの登場によって現在問題となりつつあるJIS X 0213とサロゲートペアの問題について説明します。
| Oracleを本格的に学ぶ前に読んでおくべき1冊 | |
![]() |
プロとしてのOracle入門 |
本稿の筆者、渡部亮太氏が所属する株式会社コーソルより、『プロとしてのOracle』シリーズ本の2冊目が出版されました。 内容は第4回で紹介した『プロとしての Oracle アーキテクチャ入門』の一歩手前。これからOracleを始めよう! というエンジニア向けです。データベースの成り立ちからOracle の仕組みについて、実際に、インストールや SQL 文を使ってデータベースを触りながら学べます。 |
|
| 3/3 |
文字化けに関するトラブルに強くなる【基礎編】
文字コードとは?
Oracleにおける文字コードの扱い
NLS_LANG
文字コード変換
・文字化けの原因と対処
文字化けの典型的な発生パターン
データ取得場面での文字化け
データ表示場面での文字化け
| Oracleトラブル対策の基礎知識 |
TechTargetジャパン
- IBMが歴史を変える!? 新カテゴリの製品を発表 (2012/5/25)
IBMは新たな製品カテゴリとなる「PureSystems」を発表。DB2 10とビッグデータの関係、PureSytemsの斬新さはどこかに迫ります - クラウド時代のデータ処理を支える分散KVSの可能性 (2012/5/23)
現在、高速データ処理の主流はインメモリ型データ処理だが、別の方法として分散KVSが注目を集めている。今回は分散KVSについて話を聞いた - 複数の表からデータを取り出して表示させる(2) (2012/4/23)
前回はSQLの基本的な結合構文について説明しました。今回は、より複雑な自己結合や外部結合について説明します - SQL Server、OOWにIQ、盛りだくさんの4月 (2012/4/20)
オラクルオープンワールドが3年ぶりに東京で開催されたほか、SQL Server 2012が提供開始されるなど、今月は話題が盛りだくさんです
|
|
キャリアアップ
スポンサーからのお知らせ
- - PR -
イベントカレンダー
- - PR -

