案例分享:只因在 update 语句中误用一个双引号,生产数据竟然都变成了 0
一、前言
最近经常碰到开发误删除误更新数据,这不,他们又给我找了个麻烦,我们来看下整个过程。

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

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

update tablename set source_name = “bj1062-www.meimeitu8.com北京市朝阳区常营北辰福第” 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

案例分享:只因在 update 语句中误用一个双引号,生产数据竟然都变成了 0

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

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

案例分享:只因在 update 语句中误用一个双引号,生产数据竟然都变成了 0

这几条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: 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进行比较,'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的语法高亮发现相应的问题。

来自51CTO博客作者谷力鸡的原创作品

案例分享:只因在 update 语句中误用一个双引号,生产数据竟然都变成了 0相关推荐

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

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

  2. 公式中表达单个双引号【】和空值【】的方法及说明

    有人问为什么不用三个双引号"""来表示单个双引号["]呢,如果用三个双引号来表示的话,也就是""",那么Excel会很困惑,因为你 ...

  3. 在屏幕上输出你好的python语句是_编程实现:在屏幕上输出中文字符“你好,世界”。(输出结果中不带双引号)_学小易找答案...

    [填空题]借战死者诉说战争灾难的汉乐府诗是( ). [判断题]15 的倍数有 15 . 30 . 45 . ( ) [填空题]表现贫民意欲反抗的汉乐府诗是( ). [判断题]不可以在同一台计算机上安装 ...

  4. c语言中常量单双引号,C语言常量中字元与字串 除了单引号与双引号的区别外,还有什么不同。...

    C语言常量中字元与字串 除了单引号与双引号的区别外,还有什么不同.以下文字资料是由(历史新知网www.lishixinzhi.com)小编为大家搜集整理后发布的内容,让我们赶快一起来看一下吧! C语言 ...

  5. 达梦8数据库更新语句包含单引号双引号引起转义字符执行失败解决方法全网唯一

    达梦数据库更新语句包含单引号双引号引起执行失败解决方法全网唯一 如果一个更新的UPDATE更新语句的内容包含单引号',会引起执行错误! 错误的类型不止这一种,但是都是因为内容里面包含转义字符单引号引起 ...

  6. java语言中修饰一个常量_接口中定义一个常量所用的修饰符有: (5.0分)_学小易找答案...

    [判断题]Java中的接口不允许被继承 (5.0分) [单选题]下列程序的输出结果是( ) public class Ex_36{ public static void main(String arg ...

  7. python中三个双引号 的作用是什么?1、多行注释 2、定义多行字符串(代替转义字符换行符 \n)

    作用1:多行注释 # 这是单行注释""" 这是多行注释第一行 这是多行注释第二行 这是多行注释第三行 """ 作用2:定义多行字符串(无需转 ...

  8. OSPF 协议中的一个普通区域通过ASBR 注入192.168.0.0/24~192.168.3.0/24 共4 条路由,在ABR 中配置聚合为一条聚合路由192.168.0.0/22,此时ABR 会

    OSPF 协议中的一个普通区域通过ASBR 注入192.168.0.0/24~192.168.3.0/24 共4 条路由,在ABR 中配置聚合为一条聚合路由192.168.0.0/22,此时ABR 会 ...

  9. js 中遇到英文双引号后端无法正常存储的解决方法

    js 中遇到英文双引号后端无法正常存储的解决方法 当在前端js输入框中要输入英文双引号的时候比如,"你好,北京",这个时候后端获取不到前端传输的数据.工作中遇到此文题思考很久,查资 ...

最新文章

  1. 跨链原子互换时代来临,BCH潜力无限!
  2. 网络推广是什么告诉大家如何高效提高网站权重?
  3. 仿IOS效果-带弹簧动画的ListView
  4. Spring依赖注入(DI)
  5. 【Linux】一步一步学Linux——chattr命令(115)
  6. html5app大赛,Anyoffice -HTML5大赛 悦心(基于H5开发安卓音乐app)-项目总结
  7. 当你不知道今天星期几,不妨在编辑器写下这段代码
  8. 用IE和Google 浏览器的比较。。
  9. nginx 替换返回请求中的字符
  10. 02.XMemcached的使用
  11. vue 中动态添加组件方式
  12. 代码签名证书有哪些产品
  13. java 大小写转换函数_java字符串大小写转换的两种方法
  14. 《刷新:重新发现商业与未来》读后感
  15. CocosCreator 2.4.1版本 打包微信抖音小游戏CDN配置问题
  16. 你也可以是天才,心有多大,舞台就有多大
  17. 腾讯版天眼查3年VIP免费领取!下手要快
  18. 如何批量修改多个文件的后缀名!
  19. css设置1.5倍行高,CSS怎么控制行高?
  20. 怎么拿到属于自己的那份心仪的offer

热门文章

  1. 无法重现一些战利品_命运比战利品箱还糟
  2. Mysql存储过程示例以及说明
  3. ionic新建工程并打包
  4. 斐讯dns服务器未响应,phicomm登录页面
  5. 可视化图表告诉你,这部让网友直呼过瘾的国产剧究竟火在哪里
  6. 计算机毕业设计java+ssm社会保险养老系统(源码+系统+mysql数据库+Lw文档)
  7. mysql多表查询sql优化_SQL多表查询优化
  8. webService之发布与请求
  9. (?:pattern)与(?=pattern)的区别
  10. 均衡器equalizer