[Oracle] NULL を含めた文字列連結で文字化け | Archive Redo Blog

Archive Redo Blog

DBエンジニアのあれこれ備忘録

Windows 版の Oracle9iR2(9.2.0.7) で

NULL || VARCHAR2 型の文字列 || NVARCHAR2 型の文字列

という文字列連結を行うと文字化けが発生しました。

※データベース・キャラクタ・セットは JA16SJIS、各国語キャラクタセットは AL16UTF16。

他のバージョンや環境でも同じようなことが起こるのかどうかは不明ですが注意が必要です。

例えば、以下のような VARCHAR2 と NVARCHAR2 を持つテーブルを定義し、

CREATE TABLE TEST (
(
  COL1 VARCHAR2(10),
  COL2 NVARCHAR2(10)
);

以下のようなデータを登録している環境で、

COL1                 COL2
-------------------- --------------------
ABC                  ABC
DEF
                     GHI

以下のように NULL を含んだ文字列連結を実行すると

SELECT
  COL1 || COL2 || NULL "パターン1",
  COL1 || NULL || COL2 "パターン2",
  NULL || COL1 || COL2 "パターン3",
  COL2 || COL1 || NULL "パターン4",
  COL2 || NULL || COL1 "パターン5",
  NULL || COL2 || COL1 "パターン6"
  FROM TEST;

パターン3(NULL || COL1 || COL2) のみ文字化けを起こします。

パターン1   パターン2   パターン3   パターン4   パターン5   パターン6
------------ ------------ ------------ ------------ ------------ ------------
ABCABC       ABCABC       ????     ABCABC       ABCABC       ABCABC
DEF          DEF          ?           DEF          DEF          DEF
GHI          GHI          GHI          GHI          GHI          GHI

キャラクタ・セット変換がうまくいっていないようです。

この文字化けを回避するには、NULL の代わりに空文字列('')を使うか、NVARCHAR2 型の文字列を TO_CHAR 関数を使って変換する必要があります。

SELECT
  ''   || COL1 || COL2          "パターン1",
  NULL || COL1 || TO_CHAR(COL2) "パターン2"
  FROM TEST;

パターン1   パターン2
------------ ------------
ABCABC       ABCABC
DEF          DEF
GHI          GHI


普通 NULL を連結したり、VARCHAR2型とNVARCHAR2型を混在させるようなことは少ないとは思いますが、そういうユーザーがやりそうもないことというのは、ベンダーもろくにテストしていない可能性も高いわけで、バグに遭遇しやすいものです。


ご注意を。