91

可能重复:
为什么 Oracle 9i 将空字符串视为 NULL?

我在 Oracle 10g 中有一个表,名称TEMP_TABLE只有两列 -id只是description为了演示。

该列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")

NULL在 Oracle 中,空字符串被视为一个值。


如果我删除了列not null上的约束,DESCRIPTION那么基本表结构将如下所示

+--------------+-----------+---------------+
|Name          | Null?     | Type          |
+--------------+-----------+---------------+
|ID            | NOT NULL  | NUMBER(35)    |
|DESCRIPTION   |           | VARCHAR2(4000)|
+--------------+-----------+---------------+

并且INSERT指定的两个命令都会成功。他们将在. null_''DESCRIPTIONTEMP_TABLE

现在,如果我发出以下SELECT命令,

SELECT * FROM temp_table WHERE description IS NULL;

然后它获取两个行,其中一个有一个值,另一个在列中null有一个空字符串。''DESCRIPTION

但是,以下SELECT语句从TEMP_TABLE

SELECT * FROM temp_table WHERE description='';

它甚至不检索列中包含空字符串的DESCRIPTION行。


据推测,Oracle 似乎在这里对null值和空字符串进行了不同的处理,但是对于阻止将值和空字符串都插入到具有约束的列中的语句,''情况似乎并非如此。为什么会这样?INSERTnull''not null

4

2 回答 2

118

这是因为 Oracle 在内部将空字符串更改为 NULL 值。Oracle 根本不会让插入一个空字符串。

另一方面,SQL Server 会让你做你想要达到的目标。

这里有2个解决方法:

  1. 使用另一列说明“描述”字段是否有效
  2. 在您希望它存储空字符串的“描述”字段中使用一些虚拟值。(即假设您的真实数据永远不会遇到这样的描述值,将字段设置为“stackoverflowrocks”)

当然,两者都是愚蠢的解决方法:)

于 2012-11-07T21:50:57.337 回答
34

在 oracle 中,空的 varchar2 和 null 被视为相同,您的观察表明了这一点。

当你写:

select * from table where a = '';

和写作一样

select * from table where a = null;

并不是a is null

这永远不会等于真,所以永远不要返回一行。插入时相同,NOT NULL 表示您不能插入 null 或空字符串(被视为 null)

于 2012-11-07T21:52:46.590 回答