この記事は、 JPOUG Advent Calendar 2025 10日目の記事です。
9日目は 「charade_oo4o」 さんの[JPOUG Advent Calendar] Oracle on Hyper-V 2025という記事でした。
※本記事は 2025/9/12 JPOUG Tech Talk Night #14 において、以下の資料でお話ししましたものの再編集です。
https://speakerdeck.com/sawakihideto/oracledatabasetowen-zi-kotonituite
はじめに
Oracle Databaseのシステム更改時や、他システムからのデータ移行時に文字化けや桁あふれなど、文字コードの問題に直面したことはありませんか?
例)
- AIX, HP-UX, Windows などでシフトJISをベースにしたシステムの更改時に Linux(RHEL, Oracle Linux) の UTF-8 ベースのシステムに移行する
- メインフレーム(IBM漢字コード)から Linux (UTF-8)にデータ移行する
こういった場合の注意点をご紹介します。
そもそも文字コードとは
-
コンピュータで文字を扱うための約束事
コンピュータは内部的にはバイナリデータ(ビット列)しか扱えないので、人間が使う文字との対応表が必要 -
バイナリデータと人が読む文字との対応表
例)
「あ」はShift_JISでは 82A0(16進数)→ 符号化方式(エンコーディング)
「い」はShift_JISでは 82A2(16進数)
・
・
・
「ん」はShift_JISでは 82F1(16進数)
↓
文字集合
文字コード = 文字集合 + 符号化方式(エンコーディング)
このように、文字コードは2つの概念の組み合わせです。
-
文字集合 = どの文字を扱えるか(ASCII, JIS X 0201, JIS X 0208, JIS X 0221 など)
例)- ASCIIでは「1」「A」は含まれるが「カ」「カ」「漢」は含まれない
- JIS X 0201 というJIS規格では「1」「A」「カ」は含まれるが「カ」「漢」は含まれない
(→Shift_JISで言う1Byte文字の集合) - JIS X 0208 というJIS規格では「漢」という字が含まれており、コードポイントは20-33
-
符号化方式 = どうビット列に変換するか(Shift_JIS, EUC-JP, UTF-8, UTF-16など)
例)- コードポイント20-33の文字(「漢」)はShift_JISでは16進数で8A BFに変換されるが、UTF-8ではE6 BC A2、UTF-16では 6F 22に変換される
Shift_JISなどの文字コードは複数の文字集合(JIS X 0201 と JIS X 0208など)を組み合わせて符号化しています。
あるある①
「設計書に「OracleデータベースのキャラクタセットはUTF8とする」と書いたら怒られました」
→ ‘UTF8’ というキャラクタセットは古いので非推奨(Unicode3.0以降の更新内容非対応→対応する文字が少ない、セキュリティ面の懸念も)
→ ‘AL32UTF8’ を使いましょう(Oracle社推奨)Oracle社公式サイト
[Unicodeを使用した多言語データベースのサポート] (https://docs.oracle.com/cd/E96517_01/nlspg/supporting-multilingual-databases-with-unicode.html) より抜粋
UTF8文字セットの文字のプロパティは、Unicode規格バージョン3.0以降の更新に対して保証されません。
補助文字と最新版のUnicode規格を全面的にサポートするAL32UTF8への切替えをお薦めします。
UTF8はUnicodeのUTF-8エンコーディングの適切な実装ではないため、データベース文字セットとしてUTF8を使用しないでください。UTF-8処理が予期されている場合にUTF8文字セットが使用されると、データの消失およびセキュリティの問題が発生する場合があります。このことは、XMLやURLアドレスなどのWeb関連データに特に該当します。
「当然AL32UTF8に設定するつもりでしたが、略してUTF8と書いてしまいました」
→‘UTF8’ というキャラクタセットが存在して紛らわしい。
万が一間違って設定すると Oracle データベースのキャラクタセット変更はデータベースの作り直し
→ 設計書には必ず正確に表記しましょう
あるある②
「移行後にByte数が増えてデータベースのカラムの桁あふれを起こす」
my_charCHAR(10); --JA16SJISなら漢字1文字2Byteなので5文字分
my_char:= ‘辰吉丈一郎’; --AL32UTF8 だと5文字でも15Byteで桁あふれになる
ORA-06502:PL/SQL: 数値または値のエラー: 文字列バッファが小さすぎます。
my_charCHAR(**15**); --漢字1文字3Byte分にしたら入った
→桁は拡張したけどストレージが不足することも
→見積り(サイジング)時点でだいたい何倍になりそうか分かっていないから
移行時のストレージ容量の概算見積り
- かな、漢字(JIS X 0208)部分がJA16SJIS(TILDE)で2ByteからAL32UTF8で3Byteなので、移行時のストレージ容量はざっくり1.5倍
- いわゆる半角英数のカラムが多ければ1:1でByte数は増加しないので、1.5倍より少し下がることも(経験則では1.2~1.3倍程度のストレージで足りることが多い)
→ ストレージ容量を節約したければ、何倍になる文字がどのぐらいの割合かを調べる
テーブルのカラムの桁数
テーブルのカラムの桁数については、どの文字集合が入りうるかに注意。
AL32UTF8では、いわゆる半角カナは3Byte、第三、第四水準漢字や顔文字は1文字4Byte。
WindowsVISTA以降のMS IMEで入力は可能(=混入の恐れ※)※サロゲートペアの文字は 「環境依存」と表示される
my_charCHAR(15); --漢字1文字3Byteと見積ったが…
my_char:= ‘辰吉𠀋一郎’; --AL32UTF8 だと𠀋が4Byte、計16Byteで桁あふれになる
ORA-06502:PL/SQL: 数値または値のエラー: 文字列バッファが小さすぎます。
→ 上流のアプリで入力制限しないなら、AL32UTF8での1文字は最大4Byteで見積る。
CHARではなく、VARCHAR2(20)なら末尾の空白埋めもないのでストレージ容量への影響は小さい

あるある③
文字化けが起きるのはなぜ?
- 文字コードの不一致: 保存された文字コードと、表示しようとするシステムの文字コードが異なる場合に発生
- 機種依存文字の使用: 機種依存文字は特定の環境でしか正しく表示されないため、異なる環境で文字化け
- サーバとクライアントの設定不一致: サーバとクライアントの文字コード設定が一致していない場合に発生(Oracleは自動変換してくれる)
- 規格のバージョン間の互換性: JIS規格などにもバージョン(JIS78, 83, 90, 2004)があり追加や字体の入れ替わりで文字化け
特に古いシステムやアプリケーションでは、新しい文字コードに対応していない - (略)
→ ややこしいから!(まとめるのは無理でした!すみません!)
その代わりに、文字のコード値を確認する Tips をいくつかご紹介しておきます
(参考)Oracleデータベースで文字コードを見る方法
Q. カラムに入っている文字のコードを確認するために16進数ダンプ出力するにはどうしたら良いでしょうか
A. dump 関数に 1016 の引数を与えて実行してください(16が16進数、1000がキャラクタセット表示)
実行例)name 列に「あ」が UTF-8(AL32UTF8) で格納されています(e3,81,82の3Byte)
残りは20(空白)で埋められていることが分かります。
文字化けする場合は「あ」などのデータを入れ、どの文字コードで符号化されているかを16進数ダンプで確認すると調べやすいです。

(参考)Linuxのファイルの文字のコードを確認する方法
Q. ファイルの文字のコードを確認するために16進数ダンプ出力するにはどうしたら良いでしょうか
A. odコマンドを使います。-t x1 で1Byte単位に16進数で出力、zがつけば右にASCII文字が出ます。
実行例)「a」「改行」「あ」「改行」が UTF-8 で格納されています(「あ」はe3,81,82の3Byte)
文字コードを変換するには iconvの-fに変換元、-tに変換先を指定します。
例1)SJISの「a」と「改行」はUTF-8と同じ0x0a。「あ」は0x82a0の2Byte
例2)UTF-16はBOM(Byte Order Mark=エンディアン指定)の0xfffe(リトルエンディアン指定)の後、「a」は0x6100、改行は0x0a、「あ」は「0x4230」。UnicodeのU+3042とはバイトの並びが逆になっている。
例3)CP930の「a」はEBCDICのため「0x62」、「改行」は「0x25」、IBM漢字への切り替えに「0x0e」、「あ」は「0x4481」、EBCDICへ切り戻すのに「0x0f」

(参考)リアルタイム文字コード解析ツール
文字化けの調査には、なたでラボさんの、「リアルタイム文字コード解析ツール」 (https://lab.natade.net/webapp/mojicode-kaiseki/) が便利です。

以上
