ぼんやり書いているとやってしまう事例です。
「それだけ」の内容なのですが、せっかくなので少し情報を追加しながら書こうと思います。
概要
- CHAR型の場合、末尾の空白について
-
=:データ・検索文字列ともに無視する -
Like:データ・検索文字列ともに有効である → 後方一致のLike文を書くにはTrimが必要
-
テーブルとレコードの状態
SQL> desc test02
名前 NULL? 型
----------------- -------- ----------
AA CHAR(4)
BB CHAR(10)
SQL> select '[' || aa || ']' as aa, '[' || bb || ']' as bb from test02;
AA BB
------------ ------------------------
[1 ] [bbb ]
経過: 00:00:00.01
SQL>
2つのCHAR型のカラムを持つ、いたって平凡なテーブルです。
=による検索とLikeによる検索
=による検索
CHAR型のような固定長項目の場合、後方の空白は無視してよいので以下のように取得できます。
SQL> select * from test02 where bb='bbb';
AA BB
-------- --------------------
1 bbb
経過: 00:00:00.01
SQL>
Likeによる検索
同じだろうと思ってLike文を書くとレコードが見つかりません。
SQL> select * from test02 where bb like '%b';
レコードが選択されませんでした。
経過: 00:00:00.00
SQL>
Trim(あるいはRTRIM)すると見つかります。
SQL> select * from test02 where trim(bb) like '%b';
AA BB
-------- --------------------
1 bbb
経過: 00:00:00.02
SQL> select * from test02 where rtrim(bb) like '%b';
AA BB
-------- --------------------
1 bbb
経過: 00:00:00.01
空白を補完しても取得できます。
SQL> select * from test02 where bb like '%b ';
AA BB
-------- --------------------
1 bbb
経過: 00:00:00.01
SQL>
カラム長を超えた時は?
右辺リテラルに、カラム長(10バイト)以上に半角空白を設定し検索してみます。
「概要」に書いたルールを認識していれば納得な内容ですが、ものは試しということでやってみます。
=による検索
取得できます。
SQL> select * from test02 where bb='bbb ';
AA BB
-------- --------------------
1 bbb
経過: 00:00:00.01
SQL>
Likeによる検索
取得できません。
SQL> select * from test02 where bb like '%b ';
レコードが選択されませんでした。
経過: 00:00:00.00
SQL>
あとがき
SQL標準(「ISO/IEC 9075」らしい)で仕様を確認したかったのですが、有料配布物のようで読むことができませんでした。
さらに、Trimの動作が言語によって異なることに注意が必要ですね。
Oracleの場合 半角空白のみが対象となるのに対し、.NET Framework の場合(引数なしで使用すると)全角空白やらTABコードやら改行コードやらいろんなものが消し飛びます。