0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

Oracle Database と文字コードについて

Last updated at Posted at 2025-12-10

この記事は、 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倍程度のストレージで足りることが多い)
     → ストレージ容量を節約したければ、何倍になる文字がどのぐらいの割合かを調べる
    image.png

テーブルのカラムの桁数

テーブルのカラムの桁数については、どの文字集合が入りうるかに注意。
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)なら末尾の空白埋めもないのでストレージ容量への影響は小さい
image.png

あるある③

文字化けが起きるのはなぜ?

  • 文字コードの不一致: 保存された文字コードと、表示しようとするシステムの文字コードが異なる場合に発生
  • 機種依存文字の使用: 機種依存文字は特定の環境でしか正しく表示されないため、異なる環境で文字化け
  • サーバとクライアントの設定不一致: サーバとクライアントの文字コード設定が一致していない場合に発生(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進数ダンプで確認すると調べやすいです。
image.png

(参考)Linuxのファイルの文字のコードを確認する方法

Q. ファイルの文字のコードを確認するために16進数ダンプ出力するにはどうしたら良いでしょうか
A. odコマンドを使います。-t x1 で1Byte単位に16進数で出力、zがつけば右にASCII文字が出ます。
実行例)「a」「改行」「あ」「改行」が UTF-8 で格納されています(「あ」はe3,81,82の3Byte)

image.png

文字コードを変換するには 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」
image.png

(参考)リアルタイム文字コード解析ツール

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

以上

0
0
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
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?