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

相关文章
|
4月前
|
SQL 数据库
SQL 中的 NULL 值:定义、测试和处理空数据,以及 SQL UPDATE 语句的使用
NULL 值是指字段没有值的情况。如果表中的字段是可选的,那么可以插入新记录或更新记录而不向该字段添加值。此时,该字段将保存为 NULL 值。需要注意的是,NULL 值与零值或包含空格的字段不同。具有 NULL 值的字段是在记录创建期间留空的字段。
58 0
|
4月前
|
SQL 关系型数据库 MySQL
我使用flinkcdc的sql形式进行全量同步,4张表,有两张表数据没进去,看日志,id怎么是null呢?
我使用flinkcdc的sql形式进行全量同步,4张表,有两张表数据没进去,看日志,id怎么是null呢?
117 40
|
1月前
|
SQL 关系型数据库 数据处理
详解SQL语句中的GROUP BY和聚合函数COUNT、SUM、AVG、MIN和MAX。
详解SQL语句中的GROUP BY和聚合函数COUNT、SUM、AVG、MIN和MAX。
20 0
|
2月前
|
SQL Java 关系型数据库
JDBC PreparedStatement 字段值为null导致TBase带宽飙升的案例分析
JDBC PreparedStatement 字段值为null导致TBase带宽飙升的案例分析
49 0
|
3月前
|
SQL
SQL-条件查询与聚合函数的使用
SQL-条件查询与聚合函数的使用
|
4月前
|
SQL 关系型数据库 MySQL
Mysql数据库 5.SQL语言聚合函数 语言日期-字符串函数
Mysql数据库 5.SQL语言聚合函数 语言日期-字符串函数
42 0
|
5月前
|
安全 关系型数据库 MySQL
java.sql.SQLException: null,message server: Host ora-rac2 is blocked because of many
java.sql.SQLException: null,message server: Host ora-rac2 is blocked because of many
|
5月前
|
SQL 关系型数据库 数据库
DB2 SQL Error: SQLCODE=-302, SQLSTATE=22001, SQLERRMC=null
DB2 SQL Error: SQLCODE=-302, SQLSTATE=22001, SQLERRMC=null
125 0
|
6月前
|
SQL Serverless 数据库
深入理解 SQL 聚合函数
在 SQL 数据库中,聚合函数是一组强大的工具,用于处理和分析数据。它们可以帮助您对数据进行统计、计算总和、平均值、最大值、最小值等操作。无论您是数据库开发者、数据分析师还是希望更好地了解 SQL 数据库的用户,了解聚合函数都是非常重要的。 本文将深入探讨 SQL 中的聚合函数,包括其基本语法、常见的聚合函数类型、使用示例以及一些高级用法。
342 0
|
2月前
|
机器学习/深度学习 SQL 关系型数据库
【MySQL进阶之路丨第十一篇】一文带你精通MySQL NULL值处理、正则表达式
【MySQL进阶之路丨第十一篇】一文带你精通MySQL NULL值处理、正则表达式
35 0