可能性のある複製:
Oracle 9iが空の文字列をNULLとして扱うのはなぜですか?
Oracle 10gにはTEMP_TABLE
という名前のテーブルがあり、2つの列のみがあります-デモのためにid
とdescription
です。
列id
はNUMBER(35, 0) not null
型のシーケンス生成主キーであり、列DESCRIPTION
はVARCHAR2(4000) not null
の型です。
この場合の基本的なテーブル構造は、次のようになります。
+--------------+-----------+---------------+
|Name | Null? | Type |
+--------------+-----------+---------------+
|ID | NOT NULL | NUMBER(35) |
|DESCRIPTION | NOT NULL | VARCHAR2(4000)|
+--------------+-----------+---------------+
このテーブルを作成した後、次のINSERT
コマンドを代わりに挿入しようとしています。
INSERT INTO temp_table (id, description) VALUES (1, null); ->unsuccessful
INSERT INTO temp_table (id, description) VALUES (2, ''); ->unsuccessful
not null
制約がDESCRIPTION
列に適用されるため、どちらも明らかなように失敗します。
どちらの場合でも、Oracleは文句を言います
ORA-01400: cannot insert NULL into ("WAGAFASHIONDB"."TEMP_TABLE"."DESCRIPTION")
空の文字列は、OracleでNULL
値として扱われます。
DESCRIPTION
列にnot null
制約をドロップすると、基本的なテーブル構造は次のようになります
+--------------+-----------+---------------+
|Name | Null? | Type |
+--------------+-----------+---------------+
|ID | NOT NULL | NUMBER(35) |
|DESCRIPTION | | VARCHAR2(4000)|
+--------------+-----------+---------------+
指定されたINSERT
コマンドは両方とも成功します。 null
値を持つ行と、''
のDESCRIPTION
列に空の文字列TEMP_TABLE
を持つ2つの行を作成します。
さて、次のSELECT
コマンドを発行すると、
SELECT * FROM temp_table WHERE description IS NULL;
次に、一方がnull
値を持ち、もう一方がDESCRIPTION
列に空の文字列''
を持つ両方の行をフェッチします。
ただし、次のSELECT
ステートメントは、TEMP_TABLE
から行を取得しません
SELECT * FROM temp_table WHERE description='';
DESCRIPTION
列に空の文字列がある行も取得しません。
おそらく、Oracleはnull
の値と空の文字列''
を異なる方法で処理しているように見えますが、INSERT
ステートメントとnull
値と空の文字列''
は、not null
制約を持つ列に挿入されません。なぜそうですか?
これは、Oracleが空の文字列を内部的にNULL値に変更するためです。 Oracleは単に空の文字列を挿入させません。
一方、SQL Serverでは、達成しようとしていることを実行できます。
ここには2つの回避策があります。
もちろん、両方とも愚かな回避策です:)
Oracleでは、空のvarchar2とnullは同じように扱われ、あなたの観察はそれを示しています。
あなたが書くとき:
select * from table where a = '';
書くのと同じ
select * from table where a = null;
a is null
ではありません
これは決してtrueと等しくならないため、行を返さないでください。挿入についても同じです。NOTNULLは、nullまたは空の文字列(nullとして扱われる)を挿入できないことを意味します。