Oracle 12关于nvarchar2的等于和不等于(=,!=,<>)的行为问题
Oracle 12关于nvarchar2的等于和不等于(=,!=,<>)的行为问题
在Oracle中,空的varchar2和null被视为相同,因为Oracle内部将空字符串转换为NULL值。
请考虑以下示例:
--1- 创建表
CREATE TABLE persons(
person_id NUMBER GENERATED BY DEFAULT AS IDENTITY,
first_name VARCHAR2(50) ,
last_name VARCHAR2(50) ,
PRIMARY KEY(person_id)
);
--2- 插入示例数据
insert into persons (first_name,last_name) values('n1','l1');
insert into persons (first_name,last_name) values('n2',null);
insert into persons (first_name,last_name) values('n3','');
insert into persons (first_name) values('n4');
以下查询结果如下:
select * from persons where last_name is null;
PERSON_ID FIRST_NAME LAST_NAME
2 n2
3 n3
4 n4
select * from persons where last_name is not null;
PERSON_ID FIRST_NAME LAST_NAME
1 n1 l1
我的问题:
1-为什么这些查询的结果是“未选择任何行”
select * from persons where last_name =''; -- 未选择任何行
select * from persons where last_name !=''; -- 未选择任何行
2-更重要的问题是以下查询的奇妙行为:
select * from persons where last_name !='' or last_name =''; -- 未选择任何行
问题的出现原因是因为在Oracle 12中,对于nvarchar2类型的字段,使用等于(=)或不等于(!=, <>)操作符进行比较时会出现问题。具体表现为,当将空字符串('')与nvarchar2字段进行比较时,空字符串会被转换为NULL值。而NULL值与其他NULL值之间无法进行匹配或不匹配的操作,因此查询结果始终为“no rows selected”。
解决方法是,在表达式中如果有一侧为NULL,它将始终返回false。因此,需要使用IS NULL
或IS NOT NULL
来检查NULL值。
这个问题的更重要的一点是,在以下查询中的奇怪行为:
select * from persons where last_name !='' or last_name =''; -- 等于或不等于NULL将始终返回false。 -- 因此,这个查询的结果也是no rows