首页 文章

null与Oracle中的空字符串[重复]

提问于
浏览
67

可能重复:为什么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

它们都不成功,因为在 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_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 约束 . 为什么会这样?

2 回答

  • 79

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

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

    这里有2个解决方法:

    • 使用另一列说明'description'字段是否有效

    • 为'description'字段使用一些虚拟值,您希望它存储空字符串 . (即将字段设置为'stackoverflowrocks',假设您的实际数据永远不会遇到这样的描述值)

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

  • 28

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

    当你写:

    select * from table where a = '';
    

    它和写作一样

    select * from table where a = null;
    

    而不是 a is null

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

相关问题