MySQL 中一個雙引號的錯位引發(fā)的血案
點擊上方SQL數(shù)據(jù)庫開發(fā),關(guān)注獲取SQL視頻教程
SQL專欄
一、前言
二、過程
update tablename set source_name = "bj1062-北京市朝陽區(qū)常營北辰福第" ? ? ? ? ?
where source_name ="-北京市朝陽區(qū)常營北辰福第"Harvey,我執(zhí)行了update,where條件都是對的,set的值也是對的,但是set后的字段全部都變成了0,你趕緊幫我看看,看看能不能恢復數(shù)據(jù)。


這幾條SQL的引號位置跑到了where 字段名字后面,簡化后的SQL變成了:
update tbl_name set str_col="xxx" = "yyy"那么這個SQL在MySQL他是如何進行語義轉(zhuǎn)化的呢?
可能是下面這樣的么?
update tbl_name set (str_col="xxx" )= "yyy"這樣就語法錯誤了,那么只會是下面這樣的形式,
update tbl_name set str_col=("xxx" = "yyy")而
select "xxx" = "yyy"的值是0,所以
update tbl_name set str_col="xxx" = "yyy"等價于
update tbl_name set str_col=0所以就導致了source_name字段全部更新成了0.
我們再研究下select形式這種語句會怎么樣。
mysql?[localhost]?{msandbox}?(test)?>
select?id,str_col?from?tbl_name?where?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}?(test)?>?warnings
Show?warnings?enabled.
mysql?[localhost]?{msandbox}?(test)?>?explain?extended?select?id,str_col?from?tbl_name?where?str_col="xxx"?=?"yyy"\G
***************************?1.?row?***************************
???????????id:?1
??select_type:?SIMPLE
????????table:?tbl_name
?????????type:?index
possible_keys:?NULL
??????????key:?idx_str
??????key_len:?33
??????????ref:?NULL
?????????rows:?4
?????filtered:?100.00
????????Extra:?Using?where;?Using?index
1?row?in?set,?1?warning?(0.00?sec)
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')
((`test`.`tbl_name`.`str_col` = 'xxx') = 'yyy')然后0或者1再和和'yyy'進行判斷,由于等號一邊是int,另外一邊是字符串,兩邊都轉(zhuǎn)化為float進行比較, 'yyy'轉(zhuǎn)化為浮點型為0,0和0比較恒等于1
mysql?[localhost]?{msandbox}?(test)?>?select?'yyy'+0.0;
+-----------+
|?'yyy'+0.0?|
+-----------+
|?????????0?|
+-----------+
1?row?in?set,?1?warning?(0.00?sec)
mysql?[localhost]?{msandbox}?(test)?>?select?0=0;
+-----+
|?0=0?|
+-----+
|???1?|
+-----+
1?row?in?set?(0.00?sec)這樣導致結(jié)果恒成立,也就是select語句等價于以下SQL
select id,str_col from tbl_name where 1=1;將查詢出所有的記錄。
三、小結(jié)
來源:For DBA
www.fordba.com/mysql-double-quotation-marks-accident.html
——End——
后臺回復關(guān)鍵字:1024,獲取一份精心整理的技術(shù)干貨 后臺回復關(guān)鍵字:進群,帶你進入高手如云的交流群。 推薦閱讀 這是一個能學到技術(shù)的公眾號,歡迎關(guān)注
評論
圖片
表情
