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

上传人:白大夫 文档编号:3273348 上传时间:2019-08-07 格式:DOC 页数:3 大小:19KB
返回 下载 相关 举报
SQL在MySQL他是如何进行语义转化的呢?.doc_第1页
第1页 / 共3页
亲,该文档总共3页,到这儿已超出免费预览范围,如果喜欢就下载吧!
资源描述

《SQL在MySQL他是如何进行语义转化的呢?.doc》由会员分享,可在线阅读,更多相关《SQL在MySQL他是如何进行语义转化的呢?.doc(3页珍藏版)》请在三一文库上搜索。

1、SQL在MySQL他是如何进行语义转化的呢?一、前言最近经常碰到开发误删除误更新数据,这不,他们又给我找了个麻烦,我们来看下整个过程。二、过程由于开发需要在生产环节中修复数据,需要执行120条SQL语句,需要将数据进行更新于是开发连上了生产数据库,首先执行了第一条SQLupdatetablenamesetsource_name=bj1062-北京市朝阳区常营北辰福第wheresource_name=-北京市朝阳区常营北辰福第我们仔细看了下,这个SQL,的确没有什么问题,where条件也是正常的,大意就是将这个地址的前面加字符串bj1062,是真的没有错误么?是的没有错误。开发执行完成后,结果的

2、确是符合预期。然后开发执行了剩下的SQL,都是和上面的SQL一样,将地址进行更新。执行完成后,开发懵逼了,发现source_name都变成了0,开发赶紧给我打电话说:Harvey,我执行了update,where条件都是对的,set的值也是对的,但是set后的字段全部都变成了0,你赶紧帮我看看,看看能不能恢复数据。我赶紧登上服务器,查看了这段时间的binlog,发现了大量的update tablename set source_name=0的语句,利用binlog2sql进行了解析,项目地址:binlog2sqlhttps:/github/danfengcao/binlog2sql赶紧和开发确

3、定了操作的时间点,生成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)而selectxxx=yyy的值是0,所以updatetbl

4、_namesetstr_col=xxx=yyy等价于updatetbl_namesetstr_col=0所以就导致了source_name字段全部更新成了0.我们再研究下select形式这种语句会怎么样。mysqllocalhostmsandbox(test)selectid,str_colfromtbl_namewherestr_col=xxx=yyy;+-+-+|id|str_col|+-+-+|1|aaa|2|aaa|3|aaa|4|aaa|+-+-+我们发现,这个SQL将str_col=aaa的记录也查找出来了,为什么呢?mysqllocalhostmsandbox(test)warn

5、ingsShowwarningsenabled.mysqllocalhostmsandbox(test)explainextendedselectid,str_colfromtbl_namewherestr_col=xxx=yyyG*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(Code

6、1003):/*select#1*/selecttest.tbl_name.idASid,test.tbl_name.str_colASstr_colfromtest.tbl_namewhere(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中隐式转

7、换导致的查询结果错误案例分析http:/fordba/mysql-type-convert-analysislyyy转化为浮点型为0,0和0比较恒等于1mysqllocalhostmsandbox(test)selectyyy+0.0;+-+|yyy+0.0|+-+|0|+-+1rowinset,1warning(0.00sec)mysqllocalhostmsandbox(test)select0=0;+-+|0=0|+-+|1|+-+1rowinset(0.00sec)这样导致结果恒成立,也就是select语句等价于以下SQLselectid,str_colfromtbl_namewhere1=1;将查询出所有的记录。三、小结在写SQL的过程中,一定要小心引号的位置是否正确,有时候引号位置错误,SQL依然是正常的,但是却会导致执行结果全部错误。在执行前必须在测试环境执行测试,结合IDE的语法高亮发现相应的问题。

展开阅读全文
相关资源
猜你喜欢
相关搜索

当前位置:首页 > 其他


经营许可证编号:宁ICP备18001539号-1