Oracle中的null vs空字符串

Tin*_*iny 75 string oracle null oracle10g

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

我在Oracle 10g中的表命名TEMP_TABLE,只有两列- iddescription只为示范的缘故.

该列id是序列生成的类型主键,NUMBER(35, 0) not nullDESCRIPTION是其类型VARCHAR2(4000) not null.

在这种情况下,基本的表结构如下所示.

+--------------+-----------+---------------+
|Name          | Null?     | Type          |
+--------------+-----------+---------------+
|ID            | NOT NULL  | NUMBER(35)    |
|DESCRIPTION   | NOT NULL  | VARCHAR2(4000)|
+--------------+-----------+---------------+
Run Code Online (Sandbox Code Playgroud)

创建此表后,我尝试INSERT交替插入以下命令.

INSERT INTO temp_table (id, description) VALUES (1, null); ->unsuccessful
INSERT INTO temp_table (id, description) VALUES (2, '');   ->unsuccessful
Run Code Online (Sandbox Code Playgroud)

它们都不成功,因为not nullDESCRIPTION列上强制执行约束.

在这两种情况下,Oracle都抱怨道

ORA-01400: cannot insert NULL into ("WAGAFASHIONDB"."TEMP_TABLE"."DESCRIPTION")
Run Code Online (Sandbox Code Playgroud)

空字符串NULL在Oracle中被视为值.


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

+--------------+-----------+---------------+
|Name          | Null?     | Type          |
+--------------+-----------+---------------+
|ID            | NOT NULL  | NUMBER(35)    |
|DESCRIPTION   |           | VARCHAR2(4000)|
+--------------+-----------+---------------+
Run Code Online (Sandbox Code Playgroud)

并且INSERT指定的两个命令都将成功.他们将创建两行一用一null值,另一个为空字符串''DESCRIPTION的列TEMP_TABLE.

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

SELECT * FROM temp_table WHERE description IS NULL;
Run Code Online (Sandbox Code Playgroud)

然后它获取其中一个具有null值而另一个''DESCRIPTION列中具有空字符串的行.

SELECT但是,以下语句不会从中检索任何行TEMP_TABLE

SELECT * FROM temp_table WHERE description='';
Run Code Online (Sandbox Code Playgroud)

它甚至不检索列中具有空字符串的DESCRIPTION行.


据推测,似乎Oracle 在这里对null值和空字符串的处理方式''不同,但是对于不能将值和空字符串都插入到具有约束的列中的INSERT语句似乎不是这种情况.为什么会这样?null''not null

Vai*_*sai 93

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

另一方面,SQL Server会让你做你想要实现的目标.

这里有2个解决方法:

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

当然,两者都是愚蠢的变通办法:)

  • 这是仅使用字符串还是使用其他数据类型的情况? (2认同)

Daz*_*zaL 28

在oracle中,空的varchar2和null被视为相同,并且您的观察显示了这一点.

当你写:

select * from table where a = '';
Run Code Online (Sandbox Code Playgroud)

它和写作一样

select * from table where a = null;
Run Code Online (Sandbox Code Playgroud)

并不是 a is null

永远不会等同于真,所以永远不要返回一行.在插入时,NOT NULL意味着您无法插入null或空字符串(被视为null)

  • 另外,子句`where not(a ='')`也永远不会成立,因为`a =''`是`a = null`,它的结果是`UNKNOWN`,而'not(UNKNOWN)`是`UNKNOWN `,这不是真的.有关UNKNOWN的详细信息,另请参阅http://stackoverflow.com/questions/2692046/how-oracle-10g-evaluates-null-in-boolean-expressions的答案 (5认同)