Mysql的一個雙引號錯位引發的血案

原來的sql語句如下:

update `credit_bill` set receipt_no = 'DD-20181022-89757' where receipt_no = 'DD-20181022-316736';

該sql正常執行。

變化後的sql語句如下:

update `credit_bill` set receipt_no = 'DD-20181022-89757 where receipt_no' = 'DD-20181022-316736';

此時引號錯位了,執行結果也變了。執行結果變成,把表中所有的記錄的receipt_no字段的值都更新成了0。

很神奇,但究竟是如何產生這樣的結果的呢,mysql內部又是如何轉義的呢?

轉義後的sql語句變成了這樣:

update `credit_bill` set receipt_no = ('DD-20181022-89757 where receipt_no' = 'DD-20181022-316736');

注:如果把括號提前,變成這樣:

update `credit_bill` set  (receipt_no = 'DD-20181022-89757 where receipt_no') = 'DD-20181022-316736';

是會報錯的,語法錯誤。

執行上面的sql,先執行括號內的語句,其實等同於:

select 'DD-20181022-89757 where receipt_no' = 'DD-20181022-316736';

其查詢結果爲0,所以整條sql語句就等同於:

update `credit_bill` set receipt_no = 0

謎底揭開。

 

補充:

以上情況類似的select語句如下:

select * from credit_bill where receipt_no = 'xxx' = 'yyy';

等同於:

select * from credit_bill where (receipt_no = 'xxx') = 'yyy';

執行時,括號內的語句查詢出來等於0或1。然後比較其結果和字符串'yyy'。

等號一邊是int,一邊是字符串,兩邊會都轉成float進行比較。

'yyy'轉成浮點型值爲0。如果左邊也是0,那麼就等同於0和0比較,而0恆等於0。

所以原sql等同於select * from credit_bill where 1=1;

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章