点击上方 好好学java ,选择 星标 公众号
重磅资讯,干货,第一时间送达
今日推荐:分享一套基于SpringBoot和Vue的企业级中后台开源项目,这个项目有点哇塞!个人原创100W +访问量博客:点击前往,查看更多

来源:fordba.com/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形式这种语句会怎么样。

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的语法高亮发现相应的问题。

推荐文章
  • 今天给大家推荐6个Spring Boot项目,拿来就可以赚钱!

  • 分享一套基于SpringBoot和Vue的企业级中后台开源项目,这个项目有点哇塞!

  • 圈子哥推荐一种基于Spring Boot开发OA开源产品,学习/搞外快都是不二选择!

  • 硬刚一周,3W字总结,一年的经验告诉你如何准备校招!

原创电子书历时整整一年总结的 Java面试+ Java入门技术学习指南,这是本人这几年及校招的总结,各种异步面试题已经全部进行总结,按照章节复习即可,已经拿到了了大厂提供。
原创思维导图扫码或者微信搜 程序员的技术圈子 回复 面试 领取原创电子书和思维导图。

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

  1. java去掉转义字符,双引号,全角空格

    /***清除入参全角空格及转义字符,及双引号 ????所以到底为什么ios传参过来的值会带有这些东西,contentype 的影响? ,因为使用@RequestParam注解所以要删除contenty ...

  2. php中echo单引号双引号及大括号的作用

    单引号写什么输出什么,而双引号会替换变量值.双引号里加大括号可以理解为相抵消. $var=1; #下面三种结果一样,均是1 echo $var; echo "$var"; echo ...

  3. c语言尖括号 注释,关于C语言include尖括号和双引号的对话

    A: #include "..." 和 #include <...> 有什么区别? B: 他喵的, 这么简单的问题. 尖括号是先在系统目录下找, 双引号是首先在当前目录 ...

  4. php中双引号的区别,PHP中单引号和双引号的区别

    好久没有写博客了,都忘了积累知识啦--现在开始全新的生活,重拾记录的习惯.今天要写的就是PHP中单引号和双引号的区别.在PHP中,我们可以使用单引号或者双引号来表示字符串.不过我们作为开发者,应该了解 ...

  5. 关于C语言include尖括号和双引号的对话

    A: #include "..." 和 #include <...> 有什么区别? B: 他喵的, 这么简单的问题. 尖括号是先在系统目录下找, 双引号是首先在当前目录 ...

  6. 【hive】hive----自定义UDF 函数-----时间格式化以及取出双引号的代码

    一.UDF的描述 用户自定义函数(UDF)是一个允许用户扩展HiveQL的强大的功能.用户可以使用Java编写自己的UDF,一旦将用户自定义函数加入到用户会话中(交互式的或者通过脚本执行的),它们就将 ...

  7. PHP 单引号与双引号的区别(总结)

    看好多代码有时候用单引号或双引号实现包含字符串的内容,其实简单个概括下双引号中的变量可以解析,单引号就是绝对的字符串. 1.定义字符串  在PHP中,字符串的定义可以使用单引号,也可以使用双引号.但是 ...

  8. JavaScript 中双引号、单引号和反引号的区别

    关注微信公众号:前端充电宝,获取最新原创文章: 在 JavaScript 中,单引号('')和双引号("") 经常用于创建字符串.通常情况下,使用双引号或单引号没有区别,它们最后都 ...

  9. php中的单引号与双引号详解

    一.引号定义字符串 在Php中,通常一个字符串被定义在一对引号中,如: 'I am a string in single quotes' "I am a string in double q ...

最新文章

  1. 在vue项目npm run build后,index.html中引入css和js 报MIME type问题
  2. Leetcode 167. 两数之和 II - 输入有序数组 解题思路及C++实现
  3. Eclipse旧版本Luna SR2(版本4.4.2)下载地址
  4. windows下mysql(解压版)安装教程
  5. 查看iis的log日志,并按访问量最大的天数倒排序
  6. loadrunner遇到错误继续运行
  7. c语言for嵌套循环语句,关于for嵌套循环语句的疑问
  8. 解决 vs2003 无法启动调试 没有正确安装调试器
  9. python求解微分方程组_用python解一阶微分方程组
  10. tcp多进程文件传输服务器,TCP/IP网络编程 Chap10. 多进程服务器端
  11. 深度学习——目前可用的3D人体数据集
  12. 【校招】测试开发岗-高频面试题总结
  13. 经典的双响io电平转换电路仿真
  14. drcom运行在路由器上
  15. vue实现伸缩菜单功能
  16. 计算机图标在任务栏如何取消,电脑任务栏的图标为什么从任务栏取消不了
  17. Extract Method(提炼函数)
  18. 这是写给自己的一些话
  19. curl 下载地址中有特殊字符解决方案
  20. java中字节流的分类都有哪些_Java------字节流和字符流(I)

热门文章

  1. stm32IAP代码升级小结
  2. AB1601运行后反复复位问题排查过程
  3. R语言:rep函数解析
  4. 设计模式--桥(Bridge)模式
  5. [ARM异常]-ARMV8-aarch64 异常(中断)是如何跳转到向量表的
  6. [gic]-ARM gicv3/gicv2的总结和介绍-PPT
  7. [UTCTF2020]Cube Crypto
  8. 2020-11-29(准备考试)
  9. 关于Uncaught SyntaxError: Unexpected identifier
  10. 1.12 接口(Interface)的定义和实现