SQL聚合函数SUM值为NULL引发的爆炸

简介: 在写这篇文章之前,最想提醒大家的是,开发一定不能想当然,看着没问题就不调试了,结果它就是有问题的。如果时间很紧,到了测试阶段才发现问题解决问题那就很狼狈很被动了,不要问我为什么会特别想提这个。

在写这篇文章之前,最想提醒大家的是,开发一定不能想当然,看着没问题就不调试了,结果它就是有问题的。如果时间很紧,到了测试阶段才发现问题解决问题那就很狼狈很被动了,不要问我为什么会特别想提这个。

SQL 聚合函数SUM值为NULL引发的”爆炸“。

背景

场景是这样的,一个简单的功能实现,直接以SQL语句依靠MYSQL DB直接来实现并发锁(关于锁不理解可以看这里)。语句是这样的:

update tbGift2 a, (select sum(iValue) as cnt from tbGift2 where iHostUin = '327693651' and iStatus = 1) b, (select count(*) as cnt from tbGift2 where iReceiveUin = '318713931') c set a.iStatus=1,a.iValue=2,a.iReceiveUin=3187139331, a.dtReceiveAt = now() where a.id =3 and iStatus = 0 and 8>= b.cnt+2 and 2>c.cn;

这句语句的大概意思是,要更新表数据,并且聚合sum值+2要小于等于8,count值要小于2条。咋一看,这语句没毛病吧。看起来确实也没什么问题,where条件限制了并发的发生。但是,奇怪的事情发生了,这个语句执行是不成功的!!然后代码功能就自爆了。

现场勘察

小马排查了语法,然后单独去掉8>= b.cnt+2的条件,既然执行成功了。所以这个条件很可能是false。查一下select sum(iValue) as cnt from tbGift2 where iHostUin = '327693651' and iStatus = 1语句的结果,既然是NULL。是的,你没有看错,当没有聚合记录的时候这个值就是NULL而不是0,尽管我的iValue字段是int型。NULL又如何0又如何?是的,SQL这里还有个坑,NULL是不能做比较的,只能用ISNULL,IFNULL等,用NULL作为比较的话,尽管是NULL==NULL,结果也是false。这可不是PHP哦,比较能自动转换类型。就算NULL+1=也是等于Null

解决

解决方案参考:

1、使用isnull()方法进行判断,如isnull(sum(cnt),0),其中0为默认值,如果sum(cnt)的结果为null,则赋值 0;同理此方法可用于某字段,isnull(cnt,0),这样就可以排除一些值为null的数值型字段了。而如果这样 isnull(sum(isnull(cnt,0)),0),这样就可保万无一失了。

2、使用case when else流程控制语句,如可以用"case when sum(cnt) is null then 0 else sum(cnt) end"来代替sum(cnt),其中0同上一条的意义相同。

解决后的语句:

update tbGift2 a, (select COALESCE(SUM(iValue),0) as cnt from tbGift2 where iHostUin = '327693651' and iStatus = 1) b, (select count(*) as cnt from tbGift2 where iReceiveUin = '318713931') c set a.iStatus=1,a.iValue=2,a.iReceiveUin=3187139331, a.dtReceiveAt = now() where a.id =3 and iStatus = 0 and 8>= b.cnt+2 and 2>c.cn;

执行正常。总算可以倒杯咖啡喝喝了。

image.png

别说这是我的BUG

相关文章
|
1月前
|
SQL 存储 数据库
SQL NOT NULL
【11月更文挑战第14天】
46 6
|
6月前
|
SQL 数据库
SQL SUM() 函数
SQL SUM() 函数
65 0
|
2月前
|
SQL 存储 数据库
SQL学习一:ACID四个特性,CURD基本操作,常用关键字,常用聚合函数,五个约束,综合题
这篇文章是关于SQL基础知识的全面介绍,包括ACID特性、CURD操作、常用关键字、聚合函数、约束以及索引的创建和使用,并通过综合题目来巩固学习。
63 1
|
4月前
|
SQL 数据挖掘 关系型数据库
SQL中的聚合函数:数据分析的强大工具
【8月更文挑战第31天】
182 0
|
4月前
|
SQL 数据挖掘 BI
【超实用技巧】解锁SQL聚合函数的奥秘:从基础COUNT到高级多表分析,带你轻松玩转数据统计与挖掘的全过程!
【8月更文挑战第31天】SQL聚合函数是进行数据统计分析的强大工具,可轻松计算平均值、求和及查找极值等。本文通过具体示例,展示如何利用这些函数对`sales`表进行统计分析,包括使用`COUNT()`、`SUM()`、`AVG()`、`MIN()`、`MAX()`等函数,并结合`GROUP BY`和`HAVING`子句实现更复杂的数据挖掘需求。通过这些实践,你将学会如何高效地应用SQL聚合函数解决实际问题。
64 0
|
5月前
|
Java 数据库连接 数据库
mybatis plus 更新值为null的字段
mybatis plus 更新值为null的字段
67 7
|
5月前
|
SQL
SQL NOT NULL 约束
【7月更文挑战第18天】SQL NOT NULL 约束。
57 6
|
5月前
|
SQL
SQL NOT NULL 约束
【7月更文挑战第16天】SQL NOT NULL 约束。
38 3
|
5月前
|
SQL 存储 索引
MySQL设计规约问题之为什么应该把字段定义为NOT NULL并且提供默认值
MySQL设计规约问题之为什么应该把字段定义为NOT NULL并且提供默认值
|
6月前
|
SQL Oracle 关系型数据库
SQL NULL 函数
SQL NULL 函数
43 1