暂无图片
暂无图片
6
暂无图片
暂无图片
暂无图片

MySQL 隐式转换的坑

原创 aisql 2023-10-26
400

1、发现问题

开发拿到一个SQL问我,为什么一个SQL得不到想要的结果
原本身SQL较复杂,掩盖了简单的问题。这里我用测试数据做一个场景复现,并深入了解问题背后的MySQL原理

2、问题复现

创建测试表,并插入测试数据

create table test_convert (id int, str1 varchar(50), str2 varchar(50), num DECIMAL(65,0) ) ; insert into test_convert select 3,'10004100011000510086','123',10004100011000510086 union all select 4,'10004100011000510087','aaa',10004100011000510087; select * from test_convert;
复制

image.png

表数据如上。

select * from test_convert where str1 = 10004100011000510086;
复制

image.png

执行结果如上 10004100011000510087 的数据也跟着查出来了

3、分析原因

我第一个反映就是看看MySQL是不是改写了我的语句

explain select * from test_convert where str1 = 10004100011000510086; -- 结果错误不会产生warnings show warnings;
复制

通过show warnings 查看 发现即没有警告出现,优化器也没有改变我的语句

细心的朋友可能已发现,str1字段是varchar(50)字符型, 我的sql语句比较是数值型,这里发生了隐式转换

通过查看官方文档,可以得到 字符型与数值型比较,最终是双双都转化为浮点型来比较

我以前记得转换的时候如果有异常至少会报warnings

但上述语句却没有告警

那我就再做几种场景的试验

a) 表字段为数值型,比较值为字符串,且不可转换
select * from test_convert where id = '3a'; -- 结果错误但有warnings show warnings;
复制

image.png
image.png

这种情况,结果是错误的。但MySQL给了告警

b) 表字段为字符型,比较值为数值型,可以转换,但会丢失精度
select * from test_convert where str1 = 10004100011000510086; -- 结果错误不会产生warnings show warnings;
复制

image.png
image.png
这种情况,结果是错误的。但MySQL不会告警

c) 表字段为字符型,比较值为数值型,可以转换,且不可转换
select * from test_convert where str2 = 0; -- 结果错误但有warnings show warnings;
复制

image.png
image.png
这种情况,结果是错误的。但MySQL给了告警

4、给一个总结

出现这种因隐式转换产生的错误,实在是低级错误

第一个是强制开发绝对不允许隐式转换发生
第二个是给当下一些流行的审核工具提个需求。 这种产生隐式转换的语句应该拦住,不允许执行。

「喜欢这篇文章,您的关注和赞赏是给作者最好的鼓励」
关注作者
【版权声明】本文为墨天轮用户原创内容,转载时必须标注文章的来源(墨天轮),文章链接,文章作者等基本信息,否则作者和墨天轮有权追究责任。如果您发现墨天轮中有涉嫌抄袭或者侵权的内容,欢迎发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。

文章被以下合辑收录

评论

目录
  • 1、发现问题
  • 2、问题复现
  • 3、分析原因
    • a) 表字段为数值型,比较值为字符串,且不可转换
    • b) 表字段为字符型,比较值为数值型,可以转换,但会丢失精度
    • c) 表字段为字符型,比较值为数值型,可以转换,且不可转换
  • 4、给一个总结