同事写了一个update,误用一个双引号,生产数据全变0了!

news/2024/5/19 0:27:47 标签: mysql, sql, jdbc, hive, hibernate

来源:fordba.com/sql>mysql-double-quotation-marks-accident.html

一、前言

最近经常碰到开发误删除误更新数据,这不,他们又给我找了个麻烦,我们来看下整个过程。

二、过程

由于开发需要在生产环节中修复数据,需要执行120条SQL语句,需要将数据进行更新

于是开发连上了生产数据库,首先执行了第一条SQL

update tablename set source_name = "bj1062-北京市朝阳区常营北辰福第"           where source_name =     "-北京市朝阳区常营北辰福第"

我们仔细看了下,这个SQL,的确没有什么问题,where条件也是正常的,大意就是将这个地址的前面加字符串bj1062,是真的没有错误么?是的没有错误。开发执行完成后,结果的确是符合预期。

然后开发执行了剩下的SQL,都是和上面的SQL一样,将地址进行更新。执行完成后,开发懵逼了,发现source_name都变成了0,开发赶紧给我打电话说:

Harvey,我执行了update,where条件都是对的,set的值也是对的,但是set后的字段全部都变成了0,你赶紧帮我看看,看看能不能恢复数据。

我赶紧登上服务器,查看了这段时间的binlog,发现了大量的update tablename set source_name=0的语句,利用binlog2sql进行了解析,项目地址:binlog2sql

sourcewei01

赶紧和开发确定了操作的时间点,生成flashback的SQL,进行了数据恢复,同时保留现场证据。

然后对开发执行的SQL进行了check,发现了几条很诡异的SQL:

这几条SQL的引号位置跑到了where 字段名字后面,简化后的SQL变成了:

update tbl_name set str_col="xxx" = "yyy"

那么这个SQL在MySQL他是如何进行语义转化的呢?可能是下面这样的么?

update tbl_name set (str_col="xxx" )= "yyy"

这样就语法错误了,那么只会是下面这样的形式,

update tbl_name set str_col=("xxx" = "yyy")

select "xxx" = "yyy"

的值是0,所以

update tbl_name set str_col="xxx" = "yyy"

等价于

update tbl_name set str_col=0

所以就导致了source_name字段全部更新成了0.

我们再研究下select形式这种语句会怎么样。

sql>mysql [localhost] {msandbox} (test) > select id,str_col from tbl_name where str_col="xxx" = "yyy";
+----+---------+
| id | str_col |
+----+---------+
|  1 | aaa     |
|  2 | aaa     |
|  3 | aaa     |
|  4 | aaa     |
+----+---------+

我们发现,这个SQL将str_col='aaa'的记录也查找出来了,为什么呢?

sql>mysql [localhost] {msandbox} (test) > warnings
Show warnings enabled.
sql>mysql [localhost] {msandbox} (test) > explain extended select id,str_col from tbl_name where str_col="xxx" = "yyy"\G
*************************** 1. row ***************************
           id: 1
  select_type: SIMPLE
        table: tbl_name
         type: index
possible_keys: NULL
          key: idx_str
      key_len: 33
          ref: NULL
         rows: 4
     filtered: 100.00
        Extra: Using where; Using index
1 row in set, 1 warning (0.00 sec)

Note (Code 1003): /* select#1 */ select `test`.`tbl_name`.`id` AS `id`,`test`.`tbl_name`.`str_col` AS `str_col` from `test`.`tbl_name` where ((`test`.`tbl_name`.`str_col` = 'xxx') = 'yyy')

这里他把where条件转化成了

((`test`.`tbl_name`.`str_col` = 'xxx') = 'yyy')

这个条件的首先判断str_col 和'xxx'是否相等,如果相等,那么里面括号的值为1,如果不相等,就是0 然后0或者1再和和'yyy'进行判断, 由于等号一边是int,另外一边是字符串,两边都转化为float进行比较,可以看我之前的一篇文章MySQL中隐式转换导致的查询结果错误案例分析'yyy'转化为浮点型为0,0和0比较恒等于1

sql>mysql [localhost] {msandbox} (test) > select 'yyy'+0.0;
+-----------+
| 'yyy'+0.0 |
+-----------+
|         0 |
+-----------+

1 row in set, 1 warning (0.00 sec)

sql>mysql [localhost] {msandbox} (test) > select 0=0;
+-----+
| 0=0 |
+-----+
|   1 |
+-----+
1 row in set (0.00 sec)

这样导致结果恒成立,也就是select语句等价于以下SQL

 select id,str_col from tbl_name where 1=1;

将查询出所有的记录。

三、小结

在写SQL的过程中,一定要小心引号的位置是否正确,有时候引号位置错误,SQL依然是正常的,但是却会导致执行结果全部错误。在执行前必须在测试环境执行测试,结合IDE的语法高亮发现相应的问题。

END

▼往期精彩回顾▼让人又爱又恨的 Lombok,到底该不该用
Delombok 是个啥?居然可破 Lombok?
跳槽的必要条件是有一份好的简历时候为自己的后半生考虑了——致奔三的互联网人点个赞呗

http://www.niftyadmin.cn/n/1332119.html

相关文章

如何自动加载网站的深色模式?

如何自动加载网站的深色模式?🌙 本文翻译自:Going dark (Web Edition) 🌙 来源:科技爱好者周刊:第 107 期 - 阮一峰 时间:2020-05-15 23:54:03 深色模式时代已经来临 现在有一种新的趋势 - 把东…

还在用 Guava Cache?它才是 Java 本地缓存之王!

点击上方 果汁简历 ,选择“置顶公众号”优质文章,第一时间送达Guava Cache 的优点是封装了get,put操作;提供线程安全的缓存操作;提供过期策略;提供回收策略;缓存监控。当缓存的数据超过最大值时…

uni-app 配置 eslint + prettier + stylelint + lint-staged + husky 代码格式校验

0x1 问题 更新时间:2021-01-13 19:10:25 2021-01-13 19:10:25 stylelint --fix --allow-empty-input 增加 --allow-empty-input 参数防止意外提交卡顿。 2020-11-13 14:30:02 增加 stylelint css 代码校验,增加 package.json 校验命令 改变配置文件名符…

关于Vue Loading chunk {n} failed的一些思考

关于Vue Loading chunk {n} failed的一些思考 更新时间:2020-06-02 14:52:43 0x1 问题 测试偶尔会出现这个问题,遂提出一个bug,从bug字面意思来看,有一个js的块加载失败了。丢失了一个${domain}/js/chunk-${hash}.js。 为什么会丢…

npmyarn下包无入侵加速解决方案-快的一批

1️⃣ 前言 无入侵,指的是不通过 npm config set registry http://registry.npm.taobao.org/ 等类型的命令修改 registry 达到加速的目的。 如果你写过包上传到 npm ,这种替换 registry 的方式在你使用 npm publish 进行发包的时候需要切换回 npm 官方…

全球打工人的抗争!谷歌员工希望更公平,国内只求告别996

点击上方 果汁简历 ,选择“置顶公众号”优质文章,第一时间送达新年刚开工,太平洋两岸的科技头条,都是打工人的抗争。国内,一则23岁互联网公司员工连续加班后猝死的消息震惊行业,一石激起千层浪,…

强化win10下的命令行 - 颜值和实用并存

强化win10下的命令行 - 颜值和实用并存 更新时间:2021-01-03 20:18:15 2021-10-21 10:40:57 增加 PSReadLine 插件 2021-01-04 10:49:08 抄了更多小马哥的文章!!! 2021-01-03 20:18:15 增加 PSColor 模块安装说明发现一个很好的…

大数据Spark企业级实战与Hadoop实战 | PDF PPT

今天给大家分享的是《大数据Spark企业级实战》与《Hadoop实战》等销量排行前10名的大数据技术书籍(文末领取PDF版)。这些书籍具有以下几个优点:易读、实践性强,对解决工作中遇到的业务问题具有一定启发性。本书完全从企业处理大数…