点击上方“码农突围”,马上关注

这里是码农充电第一站,回复“666”,获取一份专属大礼包

真爱,请设置“星标”或点个“在看

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


过程

由于开发需要在生产环节中修复数据,需要执行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进行了解析

赶紧和开发确定了操作的时间点,生成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形式这种语句会怎么样。

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'的记录也查找出来了,为什么呢?

mysql [localhost] {msandbox} (test) > warnings
Show warnings enabled.
mysql [localhost] {msandbox} (test) > explain extended select id,str_col from tbl_name where str_col="xxx" = "yyy"\G
*************************** 1. row ***************************id: 1select_type: SIMPLEtable: tbl_nametype: index
possible_keys: NULLkey: idx_strkey_len: 33ref: NULLrows: 4filtered: 100.00Extra: 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

mysql [localhost] {msandbox} (test) > select 'yyy'+0.0;
+-----------+
| 'yyy'+0.0 |
+-----------+
|         0 |
+-----------+1 row in set, 1 warning (0.00 sec)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的语法高亮发现相应的问题。

来源 | https://fordba.com/mysql-double-quotation-marks-accident.html

- END -
最近热文•  你偷看的小黄片,全被监视了•  一女程序员被判 9 个月:因薪酬等问题离职,rm -f * 删库,瘫痪 6 个小时•  2021年8月全国程序员薪酬终于出炉了!北京以18904元位居榜首•  外包干三年,必废!•  程序员在深圳买千万豪宅,被领导知道后,被打2星!

一条 update 语句引起的事故,这回可以长长记性了相关推荐

  1. 一条 update 语句引起的事故,这回让开发长长记性!!

    作者 | Harvey 来源 | https://www.fordba.com/mysql-double-quotation-marks-accident.html 一.前言 最近经常碰到开发误删除误 ...

  2. mysql update from 语句_MySQL高频面试题01期:一条update语句的生命历程

    在有关 MySQL 的面试时,是不是曾经有被问到过:一条 update 语句的生命历程是怎样的?今天就来聊聊这一面试题. 这篇文章通过这条语句进行讲解: update test set a=5 whe ...

  3. mysql 合并两个update_如何将多条update语句合并为一条

    需求: 如何将多条update语句合并为一条update语句: 如,update table1 set col='2012' where id='2014001' update table1 set  ...

  4. mysql执行两条update语句

    执行两条update语句,没有join关联时 update dp_auto_group_price dagp ,dp_auto_group dag set dagp.is_pub = 0 ,dag.s ...

  5. InnoDB:一条update语句执行过程

    存储引擎InnoDB下执行一条update的语句要经过哪些步骤呢?假设我们执行如下SQL,本文宏观上将执行器和存储引擎视为一体(执行器和存储引擎交互). update user_info set na ...

  6. 很多条update语句mysql优化_MySQL批量update语句优化

    对MySQL中的表进行批量update的时候,如果每个记录用一个update语句,5000条记录的话,大概需要30秒钟.下面采用的case when方法可以把5000条update拼成一条: Upda ...

  7. 一条 update 语句的生命历程

    在有关 MySQL 的面试时,是不是曾经有被问到过:一条 update 语句的生命历程是怎样的?今天就来聊聊这一面试题. 这篇文章通过这条语句进行讲解: update test set a=5 whe ...

  8. 动手为王:由一条UPDATE语句引发的一波三折深入实践(含PPT)

    关注我们获得更多精彩 编辑说明:这篇文章源自我几年前的一个演讲,当时我在『甲骨文技术大会』分享了一个关于SQL的主题,其中的一个案例推演了几个步骤,后来本文作者『刘晨』做了验证.实验,并且分享在他的博 ...

  9. 一条update语句在MySQL内部是如何执行的

    一.Server层阶段 1.连接器:负责跟客户端建立连接.获取权限.维持和管理连接 2.分析器:验证通过以后,分析器会对该语句分析, 判断是否语法有错误等. 3.优化器:选择索引,生成执行计划. 4. ...

  10. mysql基础架构(一条update语句如何执行)

    update语句如何执行? 一.流程分析 二.重要的日志模块 1.redo log 2.binlog 3.两阶段提交 三.小结 一.流程分析 与查询流程不一样的是,更新流程涉及,两个重要的日志模块,r ...

最新文章

  1. 2.11 计算机视觉现状-深度学习第四课《卷积神经网络》-Stanford吴恩达教授
  2. 释疑の语法LOCAL
  3. 制作bpmn html,BPMN 2.0规范详解
  4. 困难时拉你一把的图片_2019早上好表情图片合集 早晨祝福语动画
  5. NewCode----给定两个数R和n,输出R的n次方
  6. 发送邮件现在应用得最多的两种情况就是利用.NET自带的发送邮件和利用jmail组件来发送邮件。...
  7. 在ubuntu 16.04中安装source insight 4.0破解版
  8. 【云计算平台】VMware搭建Centos 7虚拟机
  9. amd锐龙笔记本cpu怎么样_AMD的锐龙处理器怎么样?AMD的市占率高吗?
  10. ubuntu16.04--cuda
  11. LeetCode 144. 二叉树的前序遍历(递归)(迭代)(颜色标记法)
  12. SVN回退到之前的版本
  13. 防火墙和代理服务器之间有什么区别
  14. C#中的事件(event)
  15. 论文笔记:残差神经网络(ResNet v1)
  16. 下级对上级回复已阅知_下级对上级回复已阅知_工作中回复领导,绝不能用OK!除此之外,还有四条...
  17. 领英大数据:经济寒冬,“全思维IT工程师”成企业新宠
  18. Git submodule 采坑
  19. 实力踩坑:There is no getter for property named ‘XXX‘ ‘class XXX‘
  20. C++ new malloc

热门文章

  1. SQL:pgsql新建数据表
  2. JavaScript:面向对象简单实例——图书馆
  3. 分布式存储中HDFS与Ceph两者的区别是什么,各有什么优势?
  4. 为了躲开违规电动车,我一下子撞电线杆上了
  5. 目录_视觉SLAM十四讲_0
  6. 机器学习课程笔记【十四】- 增强学习和自适应控制控制论
  7. 读《学术研究,你的成功之道》读书笔记分享给各位
  8. C#图像处理初学之平移和镜像
  9. C语言链表的操作和讲解
  10. 上海中环C位出道,自动驾驶天团横「扫」北上广