OracleとSQL Serverの空白の扱いの違いについて


業務で久々にOracleを使うことがあったのだが、OracleとSQL Serverで検索時(Where条件)の空白の扱い方に違いがあるようなので軽く検証してみた。
(検証は手持ちの環境で行ったので、最新版ではなくOracle19cとSQLServer2019で行った。)

検証

Oracle

以下のようなテーブルとデータで検証してみた。

CreateTable(Oracle).sql
CREATE TABLE CompareTestTable
(
     Seq         NUMBER
    ,ColCHAR     CHAR(10)
    ,ColVARCHAR  VARCHAR2(10)
);

INSERT INTO CompareTestTable VALUES( 1, 'aaa',  'bbb'  );       -- スペースなし
INSERT INTO CompareTestTable VALUES( 2, 'aaa ', 'bbb ' );       -- 文字列の後にスペース
INSERT INTO CompareTestTable VALUES( 3, ' aaa', ' bbb' );       -- 文字列の前にスペース
INSERT INTO CompareTestTable VALUES( 4, ' aaa ', ' bbb ' );     -- 文字列の前後にスペース
Result(Oracle).sql
select * from CompareTestTable where ColCHAR = 'aaa';       -- SEQ=1,2のデータがヒット
select * from CompareTestTable where ColCHAR = 'aaa ';      -- SEQ=1,2のデータがヒット
select * from CompareTestTable where ColCHAR = ' aaa';      -- SEQ=3,4のデータがヒット
select * from CompareTestTable where ColCHAR = ' aaa ';     -- SEQ=3,4のデータがヒット

select * from CompareTestTable where ColVARCHAR = 'bbb';    -- SEQ=1のデータがヒット
select * from CompareTestTable where ColVARCHAR = 'bbb ';   -- SEQ=2のデータがヒット
select * from CompareTestTable where ColVARCHAR = ' bbb';   -- SEQ=3のデータがヒット
select * from CompareTestTable where ColVARCHAR = ' bbb ';  -- SEQ=4のデータがヒット

OracleはChar型だと文字列の後の空白はあまり意識しなくても取ってこれるらしい。
対してVarchar2だと、文字列前後の空白まで意識しないと取ってこれないらしい。
以下に詳しい説明があったので掲載。

https://www.shift-the-oracle.com/element/data-type/varchar2-char-comparison.html#wb2ebefb

SQL Server

Oracleの時と同様、SQL Serverでも同じように検証

CreateTable(SQLServer).sql
CREATE TABLE CompareTestTable
(
	 Seq	     INT
	,ColCHAR     CHAR(10)
	,ColVARCHAR  VARCHAR(10)
)
INSERT INTO CompareTestTable VALUES( 1, 'aaa',  'bbb'  );       -- スペースなし
INSERT INTO CompareTestTable VALUES( 2, 'aaa ', 'bbb ' );       -- 文字列の後にスペース
INSERT INTO CompareTestTable VALUES( 3, ' aaa', ' bbb' );       -- 文字列の前にスペース
INSERT INTO CompareTestTable VALUES( 4, ' aaa ', ' bbb ' );     -- 文字列の前後にスペース
Result(SQLServer).sql
select * from CompareTestTable where ColCHAR = 'aaa';       -- SEQ=1,2のデータがヒット
select * from CompareTestTable where ColCHAR = 'aaa ';      -- SEQ=1,2のデータがヒット
select * from CompareTestTable where ColCHAR = ' aaa';      -- SEQ=3,4のデータがヒット
select * from CompareTestTable where ColCHAR = ' aaa ';     -- SEQ=3,4のデータがヒット

select * from CompareTestTable where ColVARCHAR = 'bbb';    -- SEQ=1,2のデータがヒット
select * from CompareTestTable where ColVARCHAR = 'bbb ';   -- SEQ=1,2のデータがヒット
select * from CompareTestTable where ColVARCHAR = ' bbb';   -- SEQ=3,4のデータがヒット
select * from CompareTestTable where ColVARCHAR = ' bbb ';  -- SEQ=3,4のデータがヒット

Char型はOracleと同じ結果となった。
対して、VarcharだとOracleと異なり、文字列後の空白は意識する必要はないらしい。

Varcharを使う場合は、OracleとSQL Serverで挙動が異なるので気を付ける必要がありそう。

【2020/04/01追記】 異なるDBMS間ではどうなるのかも検証してみた。

https://zenn.dev/em8215/articles/7952b5c76b4fb7