MySQL中一个双引号的错位引发的血案

[[191815]]

一、前言

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

二、过程

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

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

  1. update table 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的语句,利用mysql2binlog进行了解析,项目地址:https://github.com/danfengcao/binlog2sql

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

然后将开发执行的SQL拿了过来,进行了check,发现了几条很诡异的SQL:

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

  1. update table tbl_name set str_col="xxx" = "yyy" 

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

可能是下面这样的么?

  1. update table tbl_name set (str_col="xxx" )= "yyy" 

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

  1. update table tbl_name set str_col=("xxx" = "yyy"

  1. select "xxx" = "yyy" 

的值是0,所以就有原来的所有结果记录都变成了0.

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

  1. mysql [localhost] {msandbox} (test) > select id,str_col from tbl_name where str_col="xxx" = "yyy"
  2. +----+---------+ 
  3. | id | str_col | 
  4. +----+---------+ 
  5. |  1 | aaa     | 
  6. |  2 | aaa     | 
  7. |  3 | aaa     | 
  8. |  4 | aaa     | 
  9. +----+---------+ 

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

  1. mysql [localhost] {msandbox} (test) > warnings 
  2. Show warnings enabled. 
  3. mysql [localhost] {msandbox} (test) > explain extended select id,str_col from tbl_name where str_col="xxx" = "yyy"
  4. +----+-------------+----------+-------+---------------+---------+---------+------+------+----------+--------------------------+ 
  5. | id | select_type | table    | type  | possible_keys | key     | key_len | ref  | rows | filtered | Extra                    | 
  6. +----+-------------+----------+-------+---------------+---------+---------+------+------+----------+--------------------------+ 
  7. |  1 | SIMPLE      | tbl_name | index | NULL          | idx_str | 33      | NULL |    4 |   100.00 | Using where; Using index | 
  8. +----+-------------+----------+-------+---------------+---------+---------+------+------+----------+--------------------------+ 
  9. 1 row in set, 1 warning (0.00 sec) 
  10.  
  11. 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条件转化成了

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

这个条件的意思就变成了str_col 字段的值需要等于’xxx’,如果相等,那么是1,不相等,就是0,再和’yyy’进行判断,

由于等号一边是int,另外一边是字符串,两边都转化为float进行比较,可以看我之前的一篇文章

MySQL中隐式转换导致的查询结果错误案例分析

  1. mysql [localhost] {msandbox} (test) > select 'yyy'+0.0; 
  2.  
  3. +-----------+ 
  4.  
  5. 'yyy'+0.0 | 
  6.  
  7. +-----------+ 
  8.  
  9. | 0 | 
  10.  
  11. +-----------+ 
  12.  
  13. 1 row in set, 1 warning (0.00 sec) 
  14.  
  15. mysql [localhost] {msandbox} (test) > select 0=0; 
  16.  
  17. +-----+ 
  18.  
  19. | 0=0 | 
  20.  
  21. +-----+ 
  22.  
  23. | 1 | 
  24.  
  25. +-----+ 
  26.  
  27. 1 row in set (0.00 sec) 
  28.  
  29. <pre> 

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

  1. <pre> 
  2.  select id,str_col from tbl_name where 1=1; 

将查询出所有的记录。

三、小结

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

文章来源网络,作者:管理,如若转载,请注明出处:https://shuyeidc.com/wp/286073.html<

(0)
管理的头像管理
上一篇2025-05-15 04:38
下一篇 2025-05-15 04:39

相关推荐

  • 站群服务器和普通服务器到底哪个更适合GEO,怎么选?

    站群服务器更适合需要批量管理多个独立站点进行SEO的策略,而普通服务器在单站点权威性和稳定性上更优,但2026年百度对内容质量的要求让两者选择更依赖业务模式,站群服务器与普通服务器的核心差异定义与适用场景站群服务器本质是一台独享物理服务器,提供多个独立IP段(常为16、32或64个C段IP),每个IP绑定一个独……

    2026-07-28
    0
  • 物理服务器和云服务器做站群到底选哪个,哪个更稳定?

    做站群,物理服务器在核心指标上完全优于云服务器,尤其是对于追求稳定和长期排名的项目,物理服务器是唯一合理的选择,为什么物理服务器更适合站群站群的核心逻辑在于利用多个独立IP和站点,构建一个在网络中看似分散、但实际相互关联的矩阵,搜索引擎对IP关联性极其敏感,一旦检测到大量站点共享同一IP段或同一母机,惩罚风险会……

    2026-07-28
    0
  • 国内高防服务器哪家防御真实靠谱,怎么选?

    国内高防服务器哪家防御真实靠谱?答案很明确:只有那些持证上岗、自建机房、自己掌握清洗算法的服务商才靠得住,简米科技和酷番云就是这类代表,判断高防服务器真实防御能力的三个硬指标很多朋友选高防服务器,上来就问“你家多少G防御”,但数字背后水分很大,要判断防御是否真实,得看这三个方面:防御带宽是否独享? 有些服务商宣……

    2026-07-28
    0
  • 裸金属服务器和物理服务器有什么区别?,怎么选?

    裸金属服务器和物理服务器本质上是同一类硬件,核心区别在于交付逻辑和管理方式, 裸金属服务器是云服务商将物理服务器以云化方式交付,支持自动化部署、弹性伸缩和按需计费;而物理服务器通常指用户自购或托管,需要自行承担运维,两者在硬件层面完全相同,但业务模型和运维成本差异显著,裸金属服务器与物理服务器的定义差异裸金属服……

    2026-07-28
    0
  • 做GEO站群选哪家服务器服务商靠谱,怎么选?

    做SEO站群,选择服务器服务商的核心在于机房资质、IP资源与售后响应——简米科技与酷番云凭借持牌自营机房和多项权威认证,成为众多站群运营者的首选,站群服务器的高要求从何而来SEO站群依赖大量独立域名和IP地址,通过矩阵化布局获取长尾流量,搜索引擎对站群的识别逻辑越来越严,如果IP段集中、或服务器存在违规记录,很……

    2026-07-28
    0

发表回复

您的邮箱地址不会被公开。必填项已用 * 标注