数据库

本类阅读TOP10

·SQL语句导入导出大全
·SQL Server日期计算
·SQL语句导入导出大全
·SQL to Excel 的应用
·Oracle中password file的作用及说明
·MS SQLServer OLEDB分布式事务无法启动的一般解决方案
·sqlserver2000数据库置疑的解决方法
·一个比较实用的大数据量分页存储过程
·如何在正运行 SQL Server 7.0 的服务器之间传输登录和密码
·SQL中两台服务器间使用连接服务器

分类导航
VC语言Delphi
VB语言ASP
PerlJava
Script数据库
其他语言游戏开发
文件格式网站制作
软件工程.NET开发
理解NULL如何影响IN和EXITS语句

作者:未知 来源:月光软件站 加入时间:2005-2-28 月光软件站

从表面上看,IN和EXITS的SQL语句是可互换和等效的。然而,它们在处理UULL数据时会有很大的差别,并导致不同的结果。问题的根源是在一个Oracle数据库中,一个NULL值意味着未知变量,所以操作NULL值的比较函数的结果也是一个未知变量,而且任何返回NULL的值通常也被忽略。例如,以下查询都不会返回一行的值:

select 'true' from dual where 1 = null;

select 'true' from dual where 1 != null;

 

只有IS NULL才能返回true,并返回一行:

select 'true' from dual where 1 is null;

select 'true' from dual where null is null;

 

当你选择使用IN,你将会告诉SQL选择一个值并与其它每一值相比较。如果NULL值存在,将不会返回一行,即使两个都为NULL。

select 'true' from dual where null in (null);

select 'true' from dual where (null,null) in ((null,null));

select 'true' from dual where (1,null) in ((1,null));

一个IN语句在功能上相当于= ANY语句:

select 'true' from dual where null = ANY (null);

select 'true' from dual where (null,null) = ANY ((null,null));

select 'true' from dual where (1,null) = ANY ((1,null));

 

当你使用一个EXISTS等效形式的语句,SQL将会计算所有行,并忽略子查询中的值。

select 'true' from dual where exists (select null from dual);

select 'true' from dual where exists (select 0 from dual where null is null);

 

IN和EXISTS在逻辑上是相同的。IN语句比较由子查询返回的值,并在输出查询中过滤某些行。EXISTS语句比较行的值,并在子查询中过滤某些行。对于NULL值的情况,行的结果是相同的。

selectename from emp where empno in (select mgr from emp);

selectename from emp e where exists (select 0 from emp where mgr = e.empno);

 

然而当逻辑被逆向使用,即NOT IN 及NOT EXISTS时,问题就会产生:

selectename from emp where empno not in (select mgr from emp);

selectename from emp e where not exists (select 0 from emp where mgr =

e.empno);

 

NOT IN语句实质上等同于使用=比较每一值,如果测试为FALSE或者NULL,结果为比较失败。例如:

select 'true' from dual where 1 not in (null,2);

select 'true' from dual where 1 != null and 1 != 2;

select 'true' from dual where (1,2) not in ((2,3),(2,null));

select 'true' from dual where (1,null) not in ((1,2),(2,3));

这些查询不会返回任何一行。第二个查询语句更为明显,即1 != null,所以整个WHERE都为false。然而这些查询语句可变为:

select 'true' from dual where 1 not in (2,3);

select 'true' from dual where 1 != 2 and 1 != 3;

 

你也可以使用NOT IN查询,只要你保证返回的值不会出现NULL值:

selectename from emp where empno not in (select mgr from emp where mgr is not

null);

selectename from emp where empno not in (select nvl(mgr,0) from emp);

 

通过理解IN,EXISTS, NOT IN,以及NOT EXISTS之间的差别,当NULL出现在任一子查询中时,你可以避免一些常见的问题。

 


Scott Stephens已经在Oracle公司工作大于13年之久,他的工作领域包括技术支持,电子商务,市场开发,以及软件开发。





相关文章

相关软件