0
  • 聊天消息
  • 系統(tǒng)消息
  • 評論與回復(fù)
登錄后你可以
  • 下載海量資料
  • 學(xué)習(xí)在線課程
  • 觀看技術(shù)視頻
  • 寫文章/發(fā)帖/加入社區(qū)
會員中心
創(chuàng)作中心

完善資料讓更多小伙伴認(rèn)識你,還能領(lǐng)取20積分哦,立即完善>

3天內(nèi)不再提示

SQL在MySQL他是如何進(jìn)行語義轉(zhuǎn)化的呢?

電子工程師 ? 來源:李倩 ? 2018-11-29 14:24 ? 次閱讀

一、前言

最近經(jīng)常碰到開發(fā)誤刪除誤更新數(shù)據(jù),這不,他們又給我找了個(gè)麻煩,我們來看下整個(gè)過程。

二、過程

由于開發(fā)需要在生產(chǎn)環(huán)節(jié)中修復(fù)數(shù)據(jù),需要執(zhí)行120條SQL語句,需要將數(shù)據(jù)進(jìn)行更新

于是開發(fā)連上了生產(chǎn)數(shù)據(jù)庫,首先執(zhí)行了第一條SQL

updatetablenamesetsource_name="bj1062-北京市朝陽區(qū)常營北辰福第"wheresource_name="-北京市朝陽區(qū)常營北辰福第"

我們仔細(xì)看了下,這個(gè)SQL,的確沒有什么問題,where條件也是正常的,大意就是將這個(gè)地址的前面加字符串bj1062,是真的沒有錯誤么?是的沒有錯誤。開發(fā)執(zhí)行完成后,結(jié)果的確是符合預(yù)期。

然后開發(fā)執(zhí)行了剩下的SQL,都是和上面的SQL一樣,將地址進(jìn)行更新。執(zhí)行完成后,開發(fā)懵逼了,發(fā)現(xiàn)source_name都變成了0,開發(fā)趕緊給我打電話說:

Harvey,我執(zhí)行了update,where條件都是對的,set的值也是對的,但是set后的字段全部都變成了0,你趕緊幫我看看,看看能不能恢復(fù)數(shù)據(jù)。

我趕緊登上服務(wù)器,查看了這段時(shí)間的binlog,發(fā)現(xiàn)了大量的update tablename set source_name=0的語句,利用binlog2sql進(jìn)行了解析,項(xiàng)目地址:

binlog2sqlhttps://github.com/danfengcao/binlog2sql

趕緊和開發(fā)確定了操作的時(shí)間點(diǎn),生成flashback的SQL,進(jìn)行了數(shù)據(jù)恢復(fù),同時(shí)保留現(xiàn)場證據(jù)。

然后對開發(fā)執(zhí)行的SQL進(jìn)行了check,發(fā)現(xiàn)了幾條很詭異的SQL

這幾條SQL的引號位置跑到了where 字段名字后面,簡化后的SQL變成了:

updatetbl_namesetstr_col="xxx"="yyy"

那么這個(gè)SQL在MySQL他是如何進(jìn)行語義轉(zhuǎn)化的呢?

可能是下面這樣的么?

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

這樣就語法錯誤了,那么只會是下面這樣的形式,

updatetbl_namesetstr_col=("xxx"="yyy")

select"xxx"="yyy"

的值是0,所以

updatetbl_namesetstr_col="xxx"="yyy"

等價(jià)于

updatetbl_namesetstr_col=0

所以就導(dǎo)致了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|+----+---------+

我們發(fā)現(xiàn),這個(gè)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條件轉(zhuǎn)化成了

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

這個(gè)條件的首先判斷str_col 和'xxx'是否相等,如果相等,那么里面括號的值為1,如果不相等,就是0

然后0或者1再和和'yyy'進(jìn)行判斷,由于等號一邊是int,另外一邊是字符串,兩邊都轉(zhuǎn)化為float進(jìn)行比較,可以看我之前的一篇文章MySQL中隱式轉(zhuǎn)換導(dǎo)致的查詢結(jié)果錯誤案例分析http://www.fordba.com/mysql-type-convert-analysis.html'yyy'轉(zhuǎn)化為浮點(diǎn)型為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)

這樣導(dǎo)致結(jié)果恒成立,也就是select語句等價(jià)于以下SQL

selectid,str_colfromtbl_namewhere1=1;

將查詢出所有的記錄。

三、小結(jié)

在寫SQL的過程中,一定要小心引號的位置是否正確,有時(shí)候引號位置錯誤,SQL依然是正常的,但是卻會導(dǎo)致執(zhí)行結(jié)果全部錯誤。在執(zhí)行前必須在測試環(huán)境執(zhí)行測試,結(jié)合IDE的語法高亮發(fā)現(xiàn)相應(yīng)的問題。

聲明:本文內(nèi)容及配圖由入駐作者撰寫或者入駐合作網(wǎng)站授權(quán)轉(zhuǎn)載。文章觀點(diǎn)僅代表作者本人,不代表電子發(fā)燒友網(wǎng)立場。文章及其配圖僅供工程師學(xué)習(xí)之用,如有內(nèi)容侵權(quán)或者其他違規(guī)問題,請聯(lián)系本站處理。 舉報(bào)投訴
  • 服務(wù)器
    +關(guān)注

    關(guān)注

    12

    文章

    8845

    瀏覽量

    84947
  • SQL
    SQL
    +關(guān)注

    關(guān)注

    1

    文章

    751

    瀏覽量

    43985

原文標(biāo)題:MySQL 中一個(gè)雙引號的錯位引發(fā)的血案

文章出處:【微信號:DBDevs,微信公眾號:數(shù)據(jù)分析與開發(fā)】歡迎添加關(guān)注!文章轉(zhuǎn)載請注明出處。

收藏 人收藏

    評論

    相關(guān)推薦

    MySQL的執(zhí)行過程 SQL語句性能優(yōu)化常用策略

    回顧 MySQL 的執(zhí)行過程,幫助介紹如何進(jìn)行 sql 優(yōu)化。
    的頭像 發(fā)表于 12-12 10:26 ?579次閱讀
    <b class='flag-5'>MySQL</b>的執(zhí)行過程 <b class='flag-5'>SQL</b>語句性能優(yōu)化常用策略

    本地LabVIEW訪問遠(yuǎn)程mysql

    SQL SERVER我也嘗試過,連接字符串中寫入遠(yuǎn)程訪問對象的IP就可以。可是MYSQL這個(gè)數(shù)據(jù)庫沒用過,更沒用LabVIEW對其進(jìn)行過訪問操作,而且還是遠(yuǎn)程訪問。。?,F(xiàn)在的情況是,
    發(fā)表于 12-15 14:38

    MySQL數(shù)據(jù)庫Access存儲讀取SQL語句

    LabVIEW視頻教程MySQL數(shù)據(jù)庫Access存儲讀取SQL語句
    發(fā)表于 10-21 11:59

    一文讀懂SQL Server和MySQL的區(qū)別

    SQL Server和MySQL的區(qū)別主要體現(xiàn)在下面這些方面: 一、本質(zhì)區(qū)別是它們所遵循的基本原則 二、發(fā)行費(fèi)用上:MySQL不全是免費(fèi),但很便宜 三、性能方面:先進(jìn)的MySQL
    發(fā)表于 09-28 11:29 ?8.3w次閱讀

    PHP與MYSQL數(shù)據(jù)庫如何進(jìn)行交互詳細(xì)方法實(shí)驗(yàn)說明

    本文檔的主要內(nèi)容詳細(xì)介紹的是PHP與MYSQL數(shù)據(jù)庫如何進(jìn)行交互詳細(xì)方法實(shí)驗(yàn)說明。一、【實(shí)驗(yàn)?zāi)康摹?. 掌握PHP提供的各種函數(shù)與MYSQL數(shù)據(jù)庫進(jìn)行交互的方法。2. 掌握數(shù)據(jù)庫操作類
    發(fā)表于 06-13 16:58 ?13次下載

    Linux系統(tǒng)下執(zhí)行MySQLSQL文件程序免費(fèi)下載

    本文檔的主要內(nèi)容詳細(xì)介紹的是Linux系統(tǒng)下執(zhí)行MySQLSQL文件程序免費(fèi)下載。
    發(fā)表于 11-01 17:29 ?4次下載

    MySQL索引的使用問題

    一、前言 MySQL進(jìn)行SQL優(yōu)化的時(shí)候,經(jīng)常會在一些情況下,對MySQL能否利用索引有一些迷惑。譬如:1、
    的頭像 發(fā)表于 01-06 16:13 ?1555次閱讀

    為什么語義相同的情況下group by和distinct效率相同?

    語義相同,無索引的情況下:distinct效率高于group by。原因是distinct 和 group by都會進(jìn)行分組操作,但group by可能會進(jìn)行排序,觸發(fā)filesor
    的頭像 發(fā)表于 01-09 10:46 ?839次閱讀

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

    MySQLSQL Server有許多相似之處,但它們也有明顯的區(qū)別。它們之間進(jìn)行選擇時(shí),必須考慮每個(gè)系統(tǒng)的優(yōu)缺點(diǎn)。
    的頭像 發(fā)表于 05-09 17:31 ?2158次閱讀

    SQL Server與MySQL差異

    雖然SQLServer和MySQL都使用SQL作為其基礎(chǔ)語言,但它們使用不同的方言。這兩個(gè)平臺的語言約定不同,這使得為MySQL和SQLServer編寫相同的代碼變得不可行。因此,開發(fā)人員需要熟悉每個(gè)平臺的特定規(guī)則,并相應(yīng)地調(diào)整
    的頭像 發(fā)表于 05-12 14:49 ?1605次閱讀

    mysql數(shù)據(jù)庫的增刪改查sql語句

    MySQL是一種常用的關(guān)系型數(shù)據(jù)庫管理系統(tǒng),是許多網(wǎng)站和應(yīng)用程序的首選數(shù)據(jù)庫。MySQL中,我們可以使用SQL(結(jié)構(gòu)化查詢語言)進(jìn)行數(shù)據(jù)的
    的頭像 發(fā)表于 11-16 15:41 ?1088次閱讀

    將外部sql文件導(dǎo)入MySQL步驟

    將外部sql文件導(dǎo)入MySQL是一項(xiàng)非常常見的操作,它允許我們將事先準(zhǔn)備好的數(shù)據(jù)或數(shù)據(jù)庫結(jié)構(gòu)導(dǎo)入到MySQL數(shù)據(jù)庫中。本文將詳細(xì)介紹該過程的步驟,并提供一些實(shí)用的技巧和注意事項(xiàng)。
    的頭像 發(fā)表于 11-21 11:00 ?1389次閱讀

    mysqlsql server區(qū)別

    MySQLSQL Server是兩種常見的關(guān)系型數(shù)據(jù)庫管理系統(tǒng)(RDBMS),用于存儲和管理數(shù)據(jù)庫。雖然它們都支持SQL語言,但在其他方面存在一些顯著的區(qū)別。以下是MySQL
    的頭像 發(fā)表于 11-21 11:07 ?1379次閱讀

    MySQL執(zhí)行過程:如何進(jìn)行sql 優(yōu)化

    (1)客戶端發(fā)送一條查詢語句到服務(wù)器; (2)服務(wù)器先查詢緩存,如果命中緩存,則立即返回存儲緩存中的數(shù)據(jù); (3)未命中緩存后,MySQL 通過關(guān)鍵字將 SQL 語句進(jìn)行解析,并生成
    的頭像 發(fā)表于 12-12 10:19 ?359次閱讀
    <b class='flag-5'>MySQL</b>執(zhí)行過程:如<b class='flag-5'>何進(jìn)行</b><b class='flag-5'>sql</b> 優(yōu)化

    查詢SQLmysql內(nèi)部是如何執(zhí)行?

    我們知道mySQL客戶端,輸入一條查詢SQL,然后看到返回查詢的結(jié)果。這條查詢語句 MySQL 內(nèi)部到底是如何執(zhí)行的
    的頭像 發(fā)表于 01-22 14:53 ?481次閱讀
    查詢<b class='flag-5'>SQL</b><b class='flag-5'>在</b><b class='flag-5'>mysql</b>內(nèi)部是如何執(zhí)行?