Oracle 中的 null 与空字符串

可能的复制品:
为什么 Oracle 9i 将空字符串视为 NULL

我在 Oracle 10g 中有一个名为 TEMP_TABLE的表,它只有两列—— iddescription,这只是为了演示。

id是序列生成的 NUMBER(35, 0) not null类型的主键,列 DESCRIPTIONVARCHAR2(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列上强制执行的。

在这两个案例中,甲骨文都抱怨道

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值,另一行在 TEMP_TABLEDESCRIPTION列中具有空字符串 ''

现在,如果我发出以下 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约束的列中。为什么会这样?

196766 次浏览

This is because Oracle internally changes empty string to NULL values. Oracle simply won't let insert an empty string.

On the other hand, SQL Server would let you do what you are trying to achieve.

There are 2 workarounds here:

  1. Use another column that states whether the 'description' field is valid or not
  2. Use some dummy value for the 'description' field where you want it to store empty string. (i.e. set the field to be 'stackoverflowrocks' assuming your real data will never encounter such a description value)

Both are, of course, stupid workarounds :)

In oracle an empty varchar2 and null are treated the same, and your observations show that.

when you write:

select * from table where a = '';

its the same as writing

select * from table where a = null;

and not a is null

which will never equate to true, so never return a row. same on the insert, a NOT NULL means you cant insert a null or an empty string (which is treated as a null)