0
  • 聊天消息
  • 系统消息
  • 评论与回复
登录后你可以
  • 下载海量资料
  • 学习在线课程
  • 观看技术视频
  • 写文章/发帖/加入社区
会员中心
创作中心

完善资料让更多小伙伴认识你,还能领取20积分哦,立即完善>

3天内不再提示

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

电子工程师 来源:李倩 2018-11-29 14:24 次阅读

一、前言

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

二、过程

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

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

updatetablenamesetsource_name="bj1062-北京市朝阳区常营北辰福第"wheresource_name="-北京市朝阳区常营北辰福第"

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

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

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

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

binlog2sqlhttps://github.com/danfengcao/binlog2sql

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

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

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

updatetbl_namesetstr_col="xxx"="yyy"

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

可能是下面这样的么?

updatetbl_nameset(str_col="xxx")="yyy"

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

updatetbl_namesetstr_col=("xxx"="yyy")

select"xxx"="yyy"

的值是0,所以

updatetbl_namesetstr_col="xxx"="yyy"

等价于

updatetbl_namesetstr_col=0

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

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

mysql[localhost]{msandbox}(test)>selectid,str_colfromtbl_namewherestr_col="xxx"="yyy";+----+---------+|id|str_col|+----+---------+|1|aaa||2|aaa||3|aaa||4|aaa|+----+---------+

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

mysql[localhost]{msandbox}(test)>warningsShowwarningsenabled.mysql[localhost]{msandbox}(test)>explainextendedselectid,str_colfromtbl_namewherestr_col="xxx"="yyy"\G***************************1.row***************************id:1select_type:SIMPLEtable:tbl_nametype:indexpossible_keys:NULLkey:idx_strkey_len:33ref:NULLrows:4filtered:100.00Extra:Usingwhere;Usingindex1rowinset,1warning(0.00sec)Note(Code1003):/*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中隐式转换导致的查询结果错误案例分析http://www.fordba.com/mysql-type-convert-analysis.html'yyy'转化为浮点型为0,0和0比较恒等于1

mysql[localhost]{msandbox}(test)>select'yyy'+0.0;+-----------+|'yyy'+0.0|+-----------+|0|+-----------+1rowinset,1warning(0.00sec)mysql[localhost]{msandbox}(test)>select0=0;+-----+|0=0|+-----+|1|+-----+1rowinset(0.00sec)

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

selectid,str_colfromtbl_namewhere1=1;

将查询出所有的记录。

三、小结

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

声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉
  • 服务器
    +关注

    关注

    12

    文章

    9012

    浏览量

    85164
  • SQL
    SQL
    +关注

    关注

    1

    文章

    759

    浏览量

    44062

原文标题:MySQL 中一个双引号的错位引发的血案

文章出处:【微信号:DBDevs,微信公众号:数据分析与开发】欢迎添加关注!文章转载请注明出处。

收藏 人收藏

    评论

    相关推荐

    MySQL的执行过程 SQL语句性能优化常用策略

    回顾 MySQL 的执行过程,帮助介绍如何进行 sql 优化。
    的头像 发表于 12-12 10:26 619次阅读
    <b class='flag-5'>MySQL</b>的执行过程 <b class='flag-5'>SQL</b>语句性能优化常用策略

    本地LabVIEW访问远程mysql

    SQL SERVER我也尝试过,连接字符串中写入远程访问对象的IP就可以。可是MYSQL这个数据库没用过,更没用LabVIEW对其进行过访问操作,而且还是远程访问。。。现在的情况是,
    发表于 12-15 14:38

    MySQL数据库Access存储读取SQL语句

    LabVIEW视频教程MySQL数据库Access存储读取SQL语句
    发表于 10-21 11:59

    一文读懂SQL Server和MySQL的区别

    SQL Server和MySQL的区别主要体现在下面这些方面: 一、本质区别是它们所遵循的基本原则 二、发行费用上:MySQL不全是免费,但很便宜 三、性能方面:先进的MySQL
    发表于 09-28 11:29 8.3w次阅读

    PHP与MYSQL数据库如何进行交互详细方法实验说明

    本文档的主要内容详细介绍的是PHP与MYSQL数据库如何进行交互详细方法实验说明。一、【实验目的】1. 掌握PHP提供的各种函数与MYSQL数据库进行交互的方法。2. 掌握数据库操作类
    发表于 06-13 16:58 13次下载

    Linux系统下执行MySQLSQL文件程序免费下载

    本文档的主要内容详细介绍的是Linux系统下执行MySQLSQL文件程序免费下载。
    发表于 11-01 17:29 4次下载

    MySQL索引的使用问题

    一、前言 MySQL进行SQL优化的时候,经常会在一些情况下,对MySQL能否利用索引有一些迷惑。譬如:1、
    的头像 发表于 01-06 16:13 1581次阅读

    为什么语义相同的情况下group by和distinct效率相同

    语义相同,无索引的情况下:distinct效率高于group by。原因是distinct 和 group by都会进行分组操作,但group by可能会进行排序,触发filesor
    的头像 发表于 01-09 10:46 862次阅读

    深入探索SQL Server与MySQL的性能和特性

    MySQLSQL Server有许多相似之处,但它们也有明显的区别。它们之间进行选择时,必须考虑每个系统的优缺点。
    的头像 发表于 05-09 17:31 2191次阅读

    SQL Server与MySQL差异

    虽然SQLServer和MySQL都使用SQL作为其基础语言,但它们使用不同的方言。这两个平台的语言约定不同,这使得为MySQL和SQLServer编写相同的代码变得不可行。因此,开发人员需要熟悉每个平台的特定规则,并相应地调整
    的头像 发表于 05-12 14:49 1637次阅读

    mysql数据库的增删改查sql语句

    MySQL是一种常用的关系型数据库管理系统,是许多网站和应用程序的首选数据库。MySQL中,我们可以使用SQL(结构化查询语言)进行数据的
    的头像 发表于 11-16 15:41 1142次阅读

    将外部sql文件导入MySQL步骤

    将外部sql文件导入MySQL是一项非常常见的操作,它允许我们将事先准备好的数据或数据库结构导入到MySQL数据库中。本文将详细介绍该过程的步骤,并提供一些实用的技巧和注意事项。
    的头像 发表于 11-21 11:00 1583次阅读

    mysqlsql server区别

    MySQLSQL Server是两种常见的关系型数据库管理系统(RDBMS),用于存储和管理数据库。虽然它们都支持SQL语言,但在其他方面存在一些显著的区别。以下是MySQL
    的头像 发表于 11-21 11:07 1473次阅读

    MySQL执行过程:如何进行sql 优化

    (1)客户端发送一条查询语句到服务器; (2)服务器先查询缓存,如果命中缓存,则立即返回存储缓存中的数据; (3)未命中缓存后,MySQL 通过关键字将 SQL 语句进行解析,并生成
    的头像 发表于 12-12 10:19 378次阅读
    <b class='flag-5'>MySQL</b>执行过程:如<b class='flag-5'>何进行</b><b class='flag-5'>sql</b> 优化

    查询SQLmysql内部是如何执行?

    我们知道mySQL客户端,输入一条查询SQL,然后看到返回查询的结果。这条查询语句 MySQL 内部到底是如何执行的
    的头像 发表于 01-22 14:53 532次阅读
    查询<b class='flag-5'>SQL</b><b class='flag-5'>在</b><b class='flag-5'>mysql</b>内部是如何执行?