CHAR と VARCHAR2 の違い 〜 文字列比較セマンティクス 〜

CHAR と VARCHAR2(VARCHAR) は文字の比較セマンティクスにおいてスペースの取り扱いが異なる。
セマンティクスとは直訳すると「〜の意味(論)」となり、その意味がうまく消化できない。「手法」に変換すると理解しやすいだろう。

非空白埋め比較セマンティクス (Nonpadded Comparison Semantics)

比較する文字列の双方、または、どちらか一方だけでも VARCHAR2(NVARCHAR2) の可変長文字列の場合における比較方法。
人間的?にはデフォルト*1の比較セマンティクスだと思う。

以下の評価式はすべて真になる。(表中文字の _ はスペース)

文字列比較演算子比較対象 1比較対象 2
VARCHAR2CHARVARCHAR2
'abc'='abc''abc'
<>'abc___''abc___'
<'abc_''abc_'

空白埋め比較セマンティクス (Blank-Padded Comparison Semantics)

比較する文字列の双方が CHAR(NCHAR) または、文字リテラル の場合における比較方法。
若干違和感があると思われるが CHAR 型同士の比較には不可欠。

以下の評価式はすべて真になる。(表中文字の _ はスペース)

文字列比較演算子比較対象
CHARCHAR または リテラル
'abc'='abc'
'abc___'
'abc____________'
<>'_abc'
'abc_'='abc____________'

この比較は RTRIM('abc') 比較条件 RTRIM('abc______') のようにも見えるが実際は反対?でちょっと違う。 名前の通りスペースを PADDING した(満たした※) 後に比較する。短い方の文字列が長い方の文字列と同じ長さになるまでスペースが充填される。TRIM より PADDING をエミュレーションする方がメモリ使用量が少なくて速いのかも。
つまり「空白埋め」とは TRIM (FM 書式修飾子の FILL) ではなく PADDING であるということ。

vLength := GREATEST(length('abc'), length('abc______'));
RPAD('abc', vLength ) 比較条件 RPAD('abc______', vLength)

というイメージ

参考: RTRIM 関数RPAD 関数NLS_COMP 初期化パラメータ

(※) 個人的には日本語マニュアルにおいて、空白埋めの「埋め」という用語は、 あまり適切に使用されていないと思っている単語なので要注意である。
それは日本語訳において「埋め込み」と「空白埋め」でまったく反対の意味になっているからである。

反対の意味になっているのは 書式モデル(数値)における「埋め込みモード:FM」である。こちらは BLANK PADDING ではなく FILL MODE であり、直訳ではどちらも「埋める」であるもののニュアンスが異なる。空白を押し潰して無くす意味で解釈しなければならない。

それ以外にも日本語マニュアル固有の問題として外部表という用語も意味の異なる 2つの内容を示している。一方には駆動表という別名があるので、それで使い分けている人が多いと思う。

'1' = '1      ' は成立するか?

空白埋め比較セマンティクスを理解した上で以下の SQL のどれが値を返さないかわかるだろうか?

(1) 文字列 '1' と 文字列 '1     ' の比較
(2) 数値   1  と 文字列 '1     ' の比較
(3) 数値   1  と 文字列 '     1' の比較

SELECT '式は真です' x FROM DUAL WHERE '1' = '1     ' ;
SELECT '式は真です' x FROM DUAL WHERE  1  = '1     ' ;
SELECT '式は真です' x FROM DUAL WHERE  1  = '     1' ;
 
 

正解

SQL>  SELECT '式は真です' x FROM DUAL WHERE '1' = '1&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;' ;
X
--------------------
式は真です
 
SQL>  SELECT '式は真です' x FROM DUAL WHERE  1  = '1&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;' ;
X
--------------------
式は真です
 
SQL>  SELECT '式は真です' x FROM DUAL WHERE  1  = '&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;1' ;
X
--------------------
式は真です
 
結果は、すべて真となる。

文字列項目に関連する事項



CHAR と VARCHAR2 の違いの関連トピックス

日本オラクル
■ 日本オラクル 株式会社
■ オラクルマスター資格 (オラクルマスターとは
■ Oracle のライセンスがわからない…
Oracle Direct (ネットで聞いても最後はここで要確認)

*1 そういえばSEの隠語?の「〜はデフォルトだよね」は、世間ではあまり通じないですよね (^^;