【序文】
以前、SQLServer における半角・全角空白の扱いについて個人的には色々と調べたが、記憶が曖昧になってきた。
改めて調べ直し記録に残す。
【環境】
SQLServer | SQLCMD | SSMS |
---|---|---|
2017 | 14.0.1000.169 | v18.2 |
各種設定はデフォルト。 |
【後ろ空白】
文字列の比較。
A
と A
は一般的なプログラミング言語なら、後ろ空白有無によって異なる文字列と判定されるだろう。
しかし、SQLServer では等しいと判定される。
1> IF N'A' = N'A ' PRINT N'一致' ELSE PRINT N'不一致'; -- 後ろ半角空白
2> GO
一致
厳密にはこれは ANSI/ISO SQL-92 specification の仕様であり、後ろに空白を足して長さを揃えて比較するとのこと。
SQL Server - 後ろにスペースがある場合の文字列の比較について
では全角空白の場合はどうか。
1> IF N'A' = N'A ' PRINT N'一致' ELSE PRINT N'不一致'; -- 後ろ全角空白
2> GO
一致
こちらも一致。両者の後ろに混在する半角・全角が存在し、数が異なる場合も一致する。
1> IF N'A ' = N'A ' PRINT N'一致' ELSE PRINT N'不一致'; -- 後ろ半角・全角空白
2> GO
一致
【前空白】
前述はあくまでも文字列末尾の仕様であり、先頭空白は比較対象となる。
1> IF N'A' = N' A' PRINT N'一致' ELSE PRINT N'不一致'; -- 先頭半角空白
2> GO
不一致
しかし、両者の先頭空白文字数が同じであれば、半角全角の違いがあっても同じ文字列として判定される。
1> IF N' A' = N' A' PRINT N'一致' ELSE PRINT N'不一致'; -- 先頭半角・全角空白
2> GO
一致
【途中空白】
文字列の途中に存在する半角・全角空白も同様。
1> IF N'A B' = N'A B' PRINT N'一致' ELSE PRINT N'不一致'; -- 途中半角・全角空白
2> GO
一致
【半角・全角空白の比較】
つまり、文字列の比較で半角空白と全角空白は区別されない、ということになる。
1> IF N' ' = N' ' PRINT N'一致' ELSE PRINT N'不一致'; -- 半角・全角空白
2> GO
一致
と、ここまで空白に限定してきたが、そもそもデフォルトの設定では、文字列の比較で半角・全角カナを区別されない。
1> IF N'ア' = N'ア' PRINT N'一致' ELSE PRINT N'不一致'; -- ア・ア
2> GO
一致
半角空白と全角空白が区別されないのもこの仕様に沿っているだけだろう。
照合順序と Unicode のサポート - SQL Server _ Microsoft Docs
オプション | [説明] |
---|---|
文字幅を区別する (_WS) | 全角文字と半角文字を区別します。 このオプションを選択しないと、同じ文字の全角表現と半角表現は、並べ替えを行う際に SQL Server によって同じものと見なされます。 文字幅を区別しないように指定する唯一の方法は、このオプションを省略することです。 |
照合順序の設定、確認手順は以下参照。
データベースの照合順序の設定または変更 - SQL Server _ Microsoft Docs
_WS
オプションを設定すると、半角全角は区別されるようになる。
1> IF N'ア' = N'ア' PRINT N'一致' ELSE PRINT N'不一致'; -- ア・ア
2> IF N' ' = N' ' PRINT N'一致' ELSE PRINT N'不一致'; -- 半角・全角空白
3> GO
不一致
不一致
【組み込み関数】
組み込み関数も文字列比較処理が含まれていれば照合順序の影響を受ける。
照合順序 : Japanese_CI_AS
1> PRINT REPLACE(N'アアイウエオ', N'ア', N''); -- ア 削除
2> GO
イウエオ
照合順序 : Japanese_CI_AS_WS
1> PRINT REPLACE(N'アアイウエオ', N'ア', N''); -- ア 削除
2> GO
アイウエオ