可能重复:为什么Oracle 9i将空字符串视为NULL?
我在Oracle 10g中有一个名为 TEMP_TABLE
的表,只有两列 - 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
它们都不成功,因为在 DESCRIPTION
列上强制执行 not null
约束 .
在这两种情况下,Oracle都抱怨道
ORA-01400: cannot insert NULL into ("WAGAFASHIONDB"."TEMP_TABLE"."DESCRIPTION")
An empty string is treated as a NULL value in Oracle.
如果我在 DESCRIPTION
列上删除 not null
约束,那么基本表结构将如下所示
+--------------+-----------+---------------+
|Name | Null? | Type |
+--------------+-----------+---------------+
|ID | NOT NULL | NUMBER(35) |
|DESCRIPTION | | VARCHAR2(4000)|
+--------------+-----------+---------------+
并且指定的两个 INSERT
命令都将成功 . 他们会创建两行一个 null
值,另一行在 TEMP_TABLE
的 DESCRIPTION
列中创建一个空字符串 ''
.
现在,如果我发出以下 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
约束 . 为什么会这样?
2 回答
这是因为Oracle在内部将空字符串更改为NULL值 . Oracle根本不会允许插入一个空字符串 .
另一方面,SQL Server会让你做你想要实现的目标 .
这里有2个解决方法:
使用另一列说明'description'字段是否有效
为'description'字段使用一些虚拟值,您希望它存储空字符串 . (即将字段设置为'stackoverflowrocks',假设您的实际数据永远不会遇到这样的描述值)
当然,两者都是愚蠢的变通办法:)
在oracle中,空的varchar2和null被视为相同,并且您的观察显示了这一点 .
当你写:
它和写作一样
而不是
a is null
永远不会等同于真,所以永远不要返回一行 . 在插入时,NOT NULL意味着您无法插入null或空字符串(被视为null)