<kbd id="afajh"><form id="afajh"></form></kbd>
<strong id="afajh"><dl id="afajh"></dl></strong>
    <del id="afajh"><form id="afajh"></form></del>
        1. <th id="afajh"><progress id="afajh"></progress></th>
          <b id="afajh"><abbr id="afajh"></abbr></b>
          <th id="afajh"><progress id="afajh"></progress></th>

          今天Update又被雙引號坑了

          共 2710字,需瀏覽 6分鐘

           ·

          2020-08-16 08:59

          一,前言

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


          二,過程

          由于開發(fā)需要在生產(chǎn)連續(xù)中修復(fù)數(shù)據(jù),需要執(zhí)行120條SQL語句,需要將數(shù)據(jù)進行更新,于是開發(fā)連上了生產(chǎn)數(shù)據(jù)庫,首先執(zhí)行了第一條SQL

          更新 ?表名? ?source_name =? “ bj1062-北京朝陽區(qū)常營北辰福第”??

          其中?source_name =????? “-北京市朝陽區(qū)常營北辰福第”


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


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

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

          我趕緊登上服務(wù)器,查看了這段時間的binlog,發(fā)現(xiàn)縮短的更新表名set source_name = 0的語句,利用binlog2sql進行了解析


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


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


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

          更新 ?tbl_name? set ?str_col = “ xxx” ?=? “ yyy”


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


          可能是下面這樣的么?

          更新 ?tbl_name? 設(shè)置 ?(str_col = “ xxx” ?)=? “ yyy”


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

          更新 ?tbl_name? 設(shè)置 ?str_col =(“ xxx” ?=? “ yyy”


          選擇?“ xxx” ?=? “ yyy”?


          的值是0,所以

          更新 ?tbl_name? set ?str_col = “ xxx” ?=? “ yyy”


          等價于

          更新 ?tbl_name? 設(shè)置 ?str_col = 0


          所以就導(dǎo)致了source_name擴展全部更新了0。


          我們再研究下選擇形式這種語句會怎么樣。

          mysql [localhost] {msandbox}(測試)>從tbl_name選擇id,str_col,其中str_col = “ xxx” ?=? “ yyy” ;
          + ---- + --------- +
          | id | ?str_col? |
          + ---- + --------- +
          |
          ??1 ?| aaa |
          | 2 | ?aaa????? |
          |
          ??3 ?| aaa |
          | 4 | ?aaa????? |
          + ---- + --------- +


          我們發(fā)現(xiàn),這個SQL將str_col ='aaa'的記錄也查找出來了,為什么呢?

          mysql [localhost] {msandbox}(測試)> warnings
          顯示警告已啟用。
          mysql [localhost] {msandbox}(測試)>解釋擴展選擇ID,str_col from tbl_ name,其中str_col =“ xxx” =“ yyy” \ G
          ***************** ********** 1.行***************************
          ?????????? ID:1
          ? select_type:SIMPLE
          ????????表:tbl_name
          ?????????類型:索引
          可能的
          ??????????鍵:NULL 鍵:idx_str
          ????? key_len:33
          ??????????引用:NULL
          ?????????行:4已
          ?????過濾:100.00
          ????????額外:使用where;
          在集合中使用索引1行,警告1個(0.00秒)

          注意(代碼1003):/ * select#1 * /選擇? `test`。`tbl_name`。`id` ?AS? `id`,`test``tbl_name`。`str_col` ?作為? ?來自? `test`的`str_col`。`tbl_name` ?其中((`test``tbl_name`。`str_col` ?= 'xxx'的)= 'YYY')


          這里他把哪里條件轉(zhuǎn)化變成

          ((`test``tbl_name`。`str_col` ?=? 'xxx'的)=? 'YYY'


          這個條件的初步判斷str_col和'xxx'是否一致,如果替代,那么里面括號的比例1,如果不對應(yīng),就是0


          然后0或1再和和'yyy'進行判斷,由于等號一邊是int,另外一邊是字符串,兩邊都轉(zhuǎn)換為float進行比較,'yyy'轉(zhuǎn)換為浮點型為0,0和0比較恒等于1

          mysql [localhost] {msandbox}(測試)>? 選擇?'yyy' + 0.0 ;
          + ----------- +
          |?'yyy' + 0.0 ?|
          + ----------- +
          |?????????0 ?|
          + ----------- +

          1 ?行? ?集合,? 1個 ?警告(0.00 ?秒)

          的MySQL [本地主機] {msandbox}(試驗)>? 選擇?0 = 0 ;
          + ----- +
          |?0 = 0 ?|
          + ----- +
          |???1 ?|
          + ----- +
          1 ?行? ?集(0.00 ?秒)


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

          ? ?tbl_name? 選擇id,str_col? 其中?1 = 1 ;


          將查詢出所有的記錄。


          三,小結(jié)

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


          來源:對于DB?A

          www.fordba.com/mysql-double-quotation-marks-accident.html


          ——————END——————

          歡迎關(guān)注“Java引導(dǎo)者”,我們分享最有價值的Java的干貨文章,助力您成為有思想的Java開發(fā)工程師!


          瀏覽 72
          點贊
          評論
          收藏
          分享

          手機掃一掃分享

          分享
          舉報
          評論
          圖片
          表情
          推薦
          點贊
          評論
          收藏
          分享

          手機掃一掃分享

          分享
          舉報
          <kbd id="afajh"><form id="afajh"></form></kbd>
          <strong id="afajh"><dl id="afajh"></dl></strong>
            <del id="afajh"><form id="afajh"></form></del>
                1. <th id="afajh"><progress id="afajh"></progress></th>
                  <b id="afajh"><abbr id="afajh"></abbr></b>
                  <th id="afajh"><progress id="afajh"></progress></th>
                  大香蕉精品在线视频 | 精品国产91久久久久久小树林 | 久色天堂| 骚逼被操网站 | 日日夜夜三级电影网站 |