今天在工作中遇到一个问题,是一段需要从一张数据表里面抽取几列数据然后更新到一张码表里面的操作,其中数据表里面拿出来的字段有accountnumber,accountsuffix,pas_id,有一个比较,只需要将数据表里面存在,并且码表里面不存在的唯一数据放进去。下面上更新脚本:
但是这个insert操作确报错了,错误是说由于有unique construction ,non-Clustered,不能插入重复的accountnumber,XXX值。
作为一个菜鸟的我,开始实在是没怎么想通上面那段脚本有什么逻辑问题。在经过仔细查看数据规律之后有了怀疑对象column:accountstuffix.
因为在更新dicunicIdentitier表的时候使用accountnumber+accountstuffix 组合作为的唯一值,也就是说accountnumber相同,accountstuffix不同是可以insert的,而现在提示不能insert相同的accountnumber,那么说明src 这张表筛选出来的结果集里面有跟dicunicidentitier完全一样的数据。
那么第二个问题产生了,明明在where子句里面使用了not exist,去掉了这三列组合起来都不跟dic表里面相同的数据,为什么实际select出来的结果集里面还会有呢?
那么就只有一个原因了,在exist 子句里面 where子句里面的判断有问题,这三个相等的条件没有找出我们想要得到的相等的结果。其中pas_id=2 肯定不会出错,剩下accountnumber和accountstuffix。
于是我distinct了这两列,accountnumber 没有null,使用“=”肯定能得到确定结果,stuffix确有两千多条记录是null。再一想,如果stuffix是null,那么它是不能用运算符“=“进行比较计算的。
为了验证,我做了一下小实验进行验证。
第一步;我新建了两张结构一样的表:
第二步:插入数据,表一为数据表,表二为dic表。dic表里面的stuffix也会有null。
第三步:现在使用上面的脚本进行结果集查询,按照我们的本意应该得到以下结果:
accountnumber stuffix pas_id
12342 abc 1
1234098 null 1
那么现在我们看看脚本执行的结果:
比预想的过来标红的两天数据。
这个就是因为null跟null值比较 结果依旧为null造成的。
所以当要求吧这四条数据insert进去的时候,sql server抛出了错误:
先建立约束:
再insert 数据:
错误重现,验证成功。
解决办可以使用isnull进行判断然后在比较:
结论:
在where子句里面使用”=“运算符时要多考虑null值情况,可以试用 function isnull先对null值进行处理再进行判断。
--
努力做好一件事,就是莫大的成功。