SQL升级Oracle挖的Null坑,你懂的!

时间:2021-03-14 06:41:02
  最近公司做系统数据库升级,主要由原来的SQL数据库升级Oracle数据库,对于拥有千万级数据库的实用系统来说,迁移不是件容易的时,光数据同步就需要很久,更别说要修改升级原来的SQL库使用的存储过程和视图了。
  当然经过团队小强们的不懈努力,还是一举攻破了这道门槛,存储过程全部替换,数据全部同步,然,不好意思说出But,但是正是有了这个But也就有了这篇博文;

一、定性思维

问题:我们常常在SQL的语句用这样的查询,不知道大家有没有注意到:
select * 表名 where isnull(列名,'')=''
这种常规的写法在SQL中应用很广泛,只是因为在设计之初,我们做筛选的列名设置的可以为空,并且后续的数据添加过程中,可能设置了 空(‘’) 插入;所以我们筛选的时候要 包括空(‘’)和null的数据,于是就有了上述的语句;

二、Oracle自带不同

类似上诉SQL的写法,Oracle的写法确是这样
select * 表名 where NVL(列名,'')=''
但是事实证明,Oracle这种完全模仿SQL的写法是不能得到你想要的结果的,因为Oracle里面 空(“)=空(“) 是false的表现;Because在Oracle中空(”)就是null;而Oracle中让null =(等于)null 显然,Oracle君是不同意的,至少应该是 null is null 才是正确的写法;

三、实例证明

满汉全null来一遍(SQL版)
SQL升级Oracle挖的Null坑,你懂的!
SQL升级Oracle挖的Null坑,你懂的!
SQL升级Oracle挖的Null坑,你懂的!
满汉全null再来一遍(Oracle版)
SQL升级Oracle挖的Null坑,你懂的!
大家可以比较下结果,基本上是反过来的(除了c3,c4,c5,c7),所以我不得不承认我之前可能没有注意到这个坑,但是如今碰到了,想必也令我记忆深刻啦~~~

四、总结性的侃侃

Oracle中关于null(空值)的定义(来自百度):
1、等价于没有任何值、是未知数(这里想到了数学里最常见的 x)。 
2、NULL与0、空字符串、空格都不同。 
3、对空值做加、减、乘、除等运算操作,结果仍为空。 
4、NULL的处理使用NVL函数。 
5、比较时使用关键字用“is null”和“is not null”。 
6、空值不能被索引,所以查询时有些符合条件的数据可能查不出来,count(*)中,用nvl(列名,0)处理后再查。 
7、排序时比其他数据都大(索引默认是降序排列,小→大),所以NULL值总是排在最后。
 
参见Oracle help 文档:
SQL升级Oracle挖的Null坑,你懂的!
 SQL升级Oracle挖的Null坑,你懂的!
SQL升级Oracle挖的Null坑,你懂的!
 
SQL升级Oracle挖的Null坑,你懂的!

Good Luck For You!