Oracle で日本語を取り扱うときの文字コード

オラクルの CHAR および VARCHAR2 などに分類される標準文字列型で使用される文字コードを Database Characterset と呼び、 NCHAR および NVARCHAR2 などの各国語文字列型で使用される文字コードを National Characterset と呼ぶ。

マルチバイト・キャラクタセット(ダブルバイト・キャラクタセット)

日本を含むアジア圏などにおいて使用されるキャラクタセットは、文字種が多く 1 バイトでは表現不可能なため 2バイト以上で表現されている。
一般的に全角文字=マルチバイト・キャラクタと話していることも多いが厳密には間違いとなる。
(それで誤解した(された)ことは無く、問題になったこともないので大丈夫かと思う)

以下は日本語をサポートするキャラクタセットの代表的なもの
英数字、スペース,記号(_,$,#,など)は 1 バイト(UTF-16 は例外)
半角カタカナ、ひらがな、漢字などの全角文字は 2 バイト以上で構成される。

Shift_JIS の場合、半角カタカナは 1 バイトのため、他のプラットフォームの EUC 環境にデータを移植する場合によく問題になる。

Database Characterset (文字コード)NLS 表記
Shift_JIS1〜2バイトJA16SJISTILDE (9iR2以降)
JA16SJIS
EUC-JP1〜2(3) バイト*2JA16EUCTILDE (9iR2以降)
JA16EUC
UTF-81〜3 バイト*3(or 6 バイト=3×2※)
AL32UTF8 で補助文字 参照
1 バイト:ASCII
2 バイト:非漢字、記号、ギリシャ文字(Ωαβ…)、ロシア文字(АБ…)
3 バイト:半角カナ、ひらがな、漢字
AL32UTF8
(UTF8は旧形式 AL32UTF8を使う)
Unicode 3.2 Oracle 10g
Unicode 4.0 サポート Oracle 10g Release2
Unicode 5.0 サポート Oracle 11g
UTF-EBCDIC1〜4 バイトUTFE


National Characterset*4NLS 表記
UTF-81〜3 バイト(UTF8 はUnicode 3.0まで)
日本語文字は 3 バイト
特殊文字 4 バイト(Oracle 10g 未サポート)
5 バイト以上はわかりません。規格上だけ?
UTF8
UTF-162 バイト(アルファベット、日本語)
4 バイト(特殊文字)
AL16UTF16
Unicode 5.0 サポート Oracle 11g


それ以外の文字コード備考
UCS-22 バイトマルチバイト・キャラクタセットの場合に CLOB がデータ格納に使用するキャラクタセット ⇒ データ型の内部形式
Java や Win NT系の UNICODE
UCS-44 バイト

AL32UTF8 で補助文字(4バイトの文字)の扱い (JIS X 0213:2004 / 第3・4水準漢字)

Windows Vista による JIS X 0213:2004 サポートによって 4 バイト文字の問題が顕在化する可能性も…

Oracle 10g R1 は 3 バイトまでの Unicode 3.2
Oracle 10g R2 から AL32UTF32 と AL16UTF16 で Unicode 4.0 サポート Oracle 10g Release2
Oracle 11g から AL32UTF32 と AL16UTF16 で Unicode 5.0 サポート Oracle 11g

マニュアル上の表記では(Oracle 10g R1 以前まで?)

UTF8 データベースに補助文字が挿入されても、データベース内のデータは
破損しません。 補助文字は 6バイトを占める 2つの別個のユーザー定義文字
として処理されます。

と書かれている。つまり 4バイト文字は 6バイト消費するということのようである。(つまり AL32UTF8 には Oracle による拡張が施されている。NCHAR の UTF8 は???)
但し、未確認 & TTC レイヤ、ミドルウェアのバージョンによっては予想外の動作になるかもしれない。

クライアント(顧客)が Windows Vista 使用を解禁した後に発生が予想されるエラー

Unicode UTF-16

Oracle は UTF-16 のうちで UTF-16BE のみサポートしている。
UTF-16LE(AL16UTF16LE) は変換専用(⇒ CONVERT)に存在するが Database Characterset および National Characterset に利用できない。
e-mail で良く利用される ISO2022-JP も変換専用のキャラクタセットとして存在する。

Oracle CharactersetStructureWord
(byte)
US7ASCIIASCIIAΩア(半角)
41---
UTF8 , AL32UTF8UTF-8AΩ
41CE.A9E8.AA.9EEF.BD.B1
AL16UTF16UTF-16BEAΩ
00.4103.A98A.9EFF.71
(UTF16)*5UTF-16LEAΩ
41.00A9.039E.8A71.FF
-UTF-32BEAΩ
00.00.00.4100.00.03.A900.00.8A.9E00.00.FF.71
UTF-32LEAΩ
41.00.00.00A9.03.00.009E.8A.00.0071.FF.00.00

BE(Big Endian):ビッグエンディアン(ビックインディアン) バイトオーダ
LE(Big Endian):リトルエンディアン(リトルインディアン) バイトオーダ
この用語の説明に、たま〜に大小のインディアンの民族衣装をつけた挿絵があることがありますが
あれは引っ掛けです。Endian(フィクション) ≠ Indian(ノンフィクション) です。

Indian は インド人と勘違いしたことから生まれたもので、Endian は卵をあたま (little) とおしり (big) のどちらから割るか で争いになってしまった Big End + ian(人) と Litte End + ian(人) という、物語にでてくるの人種の名前で CPU の主導権争いのときの様子を滑稽にあらわしているものだと思います。

Big Endian は Motorola や Sun 勢力で Litte Endian は Intel や Zilog 勢力です。まるで今の次世代 DVD 規格のような状態だったような… Z80 って知っていますか?

キャラクタセット名/文字コードの確認方法

現在のデータベースのキャラクタセット、各国語キャラクタセットを確認するには (⇒ NLS_CHARSET_ID、NLS_CHARSET_NAME 関数

SELECT NLS_CHARSET_NAME(NLS_CHARSET_ID('CHAR_CS')),
       NLS_CHARSET_NAME(NLS_CHARSET_ID('NCHAR_CS')) FROM DUAL;

または

SELECT PARAMETER, VALUE
  FROM NLS_DATABASE_PARAMETERS
 WHERE PARAMETER IN ('NLS_CHARACTERSET', 'NLS_NCHAR_CHARACTERSET');

を使用する。
NLS_CHARACTERSET: データベース・キャラクタセット
NLS_NCHAR_CHARACTERSET: 各国語キャラクタセット

SQL*Plus コマンド の SHOW コマンド

SQL> SHOW PARAMETER NLS_ 

では使用している文字コードの確認はできない。

参考: データベースの文字コードを変更する



関連事項

(余談) VARCHAR は、なんと呼びますか?

私は、発音のしやすさから、つい「バーチャー」と呼んでいます、但し CHAR はキャラと呼ぶ、優柔不断さ。
そして、呼び方にうるさい人と仕事をするときには、「バーキャラ」と呼ぶくらい徹底して優柔不断です。 (^^;

この「バーチャー」、汎用機経験者(COBOL のみ?)は、これを特に嫌っているように思えます。
Oracle には VIRTUAL 型はないはず*1ですが 「バーチャー」は VIRTUAL をイメージするので「バーキャラ」が正しいという王道で力説しているかと思います。

「バーチャー」を否定する資料はあっても、正当化する資料が存在するとは思えませんが、 とりあえず Oracle 関連の掲示板とオフィシャルサイトでは、関連する公式な資料は見つけられませんでした…おしまい。

日本オラクル
■ 日本オラクル 株式会社
■ オラクルマスター資格 (オラクルマスターとは
■ Oracle Web セミナー

*1 書式モデル(数値) V フォーマットがある位だと思います。