mysql 隱式轉換引起的bug

2021-10-22 19:12:19 字數 1804 閱讀 3800

提問

乙個粗心,括號不小心打錯了地方,猜猜會是什麼執行結果?

t_***表order_no為varchar型別。

select * from t_*** where order_no in ('u123','u234' and type in (10,11));

語法錯誤?

row 0?

答案

實際情況是,這句sql並沒有語法錯誤,而是將全部資料返回出來。

本以為這句sql會報語法錯誤,但萬萬沒想到竟然可以執行成功,而且會導致where子句的失效,讓我們一起盤根問底一下。

首先是詞法分析

mysql通過關鍵字將sql語句進行解析,並生成一棵對應的「解析樹」。mysql解析器將使用mysql語法規則驗證和解析查詢。

1. 本例中,in將被分解為【'u123'】、【'u234' and type in (10,11)】兩部分,也同時等效於order_no=('u123') or order_no=('u234' and type in (10,11)),前一段必定是false,出問題的部分其實就在後面這段。

2. 猜想下('u234' and type in (10,11))的結果是什麼?因為中間有and邏輯運算子,其結果將為布林型(底層為tinyint(1)),0/1這樣的值

那為什麼後面一段會被認為是true呢?這就要從varchar與int的比較說起,這也是乙個會隱藏大坑的地方《資料型別隱式轉換》

資料型別隱式轉換分析

文件我們只看原版:

首先我們列舉下已知的隱式轉換規則:

兩個引數至少有乙個是 null 時,比較的結果也是 null,例外是使用 <=> 對兩個 null 做比較時會返回 1,這兩種情況都不需要做型別轉換

兩個引數都是字串,會按照字串來比較,不做型別轉換

兩個引數都是整數,按照整數來比較,不做型別轉換

十六進製制的值和非數字做比較時,會被當做二進位制串

有乙個引數是 timestamp 或 datetime,並且另外乙個引數是常量,常量會被轉換為 timestamp

有乙個引數是 decimal 型別,如果另外乙個引數是 decimal 或者整數,會將整數轉換為 decimal 後進行比較,如果另外乙個引數是浮點數,則會把 decimal 轉換為浮點數進行比較

所有其他情況下,兩個引數都會被轉換為浮點數再進行比較

【order_no=('u234' and type in (10,11))】出問題的條件表示式,order_no是字串、後面的是tinyint(1),等價於order_no=0這個條件表示式,**了,命中了7號策略

我們又要細說,字元轉數字的過程

字串轉為數字

乙個字串是會與int 0匹配上的,這也是乙個經典的安全問題,那為什麼字串或者明確說首字母非數字的字串會與int 0匹配上呢?

再來猜測一下,這些表示式的結果會是什麼?

select '123'=123,'123a'=123,'a123'=123---------------------1  1  0---------------------

當字串轉為數字的時候,原則是從左邊開始處理:

如果字串的第乙個字元就是非數字的字元,那麼轉換為數字就是0

如果字串以數字開頭

如果字串中都是數字,那麼轉換為數字就是整個字串對應的數字

如果字串中存在非數字,那麼轉換為的數字就是開頭的那些數字對應的值

所以order_no變成了0,與右側的0匹配上了

這就是這個問題的分析過程

js 引起的隱式轉換

var undefined undefined null true 1 true true 2 true false 0 false true 0 true nan nan false false true true alert true alert false alert 0 true alert...

mysql 隱式轉換 mysql中的隱式轉換

在mysql查詢中,當查詢條件左右兩側型別不匹配的時候會發生隱式轉換,可能導致查詢無法使用索引。下面分析兩種隱式轉換的情況 看表結構 phone為 int型別,name為 varchar 兩種情況都可以用到索引,這次等號右側是 2 注意帶單引號喲,左側的索引欄位是int型別,因此也會發生隱式轉換,但...

mysql隱式轉換

定義 當操作符與不同型別的運算元一起使用時,會發生型別轉換以使運算元相容。則會發生轉換隱式 舉乙個常見例子 1 我們先建立乙個表,有關手機號查詢 create table user id int 11 not null primary keyauto increment phone varchar ...