背景
在进行某项系统测试时,遇到选择部分保单更新为加急状态后,未选中的保单也同步更新成了加急状态。
经过比对分析,发现是SQL查询在数据库设计为字符型的字段,SQL语句中用了数值型来查询时,查询结果结果会多了末尾两位不一致的值,如下图,100320201000195806搜出100320201000195812等值:
百因必有果,通过度娘,首先了解到原来在MySQL中,当操作符与不同类型的操作数一起使用时,会发生类型转换以使操作数兼容,即字符型字段与数值型值比较时,会进行隐式类型转换:都转换为数值型。
即,数据库字段值为字符型1234,查询条件为数值1234的时候,数据库字符型1234会转换为数值型1234,能够查询到对应值。
但为什么数值型100320201000195806除了搜索出100320201000195806还有100320201000195812这样的字符型结果?
问题根因
数值隐式转换成了double型,考虑数值可能出现溢出。根据DOUBLE 类型固定占用8个字节(64位),并且需要一位表示符号,11位表示指数,2的52次方-1:2^53 = 9007199254740992,当输入的数值大于9007199254740992时,存在数值溢出 。
也就是当数字超过16位以后,数据库不会报错,而是溢出后转为最接近的值入库,如下图:设置字段类型为double型,9007199254740993入库后显示为9007199254740992。
并且如下图测试,溢出入库的数据转化后有某种没明显规律的规则:
同理,取数据时,大于9007199254740992的数值也会发生转换,如下图,9007199254740993可以检索出9007199254740992的数值:
所以Bug产生过程为:18位数值类型 为double类型(1.003202010001958E+18),数据库查询时将business_no 变成(1.003202010001958E+18),数据库存的business_no值也根据隐式类型转换原则也转为了double类型。
本文源自第六十六期《51测试天地》
《从Mysql隐式类型转换延伸出的测试点思考》一文
查看更多精彩内容,请点击下载:
版权声明:本文出自《51测试天地》第六十五期。51Testing软件测试网及相关内容提供者拥有51testing.com内容的全部版权,未经明确的书面许可,任何人或单位不得对本网站内容复制、转载或进行镜像,否则将追究法律责任。