瞭解MySQL的隱式轉化
在MySQL中。當我們對不同型別的值進行比較的時候,為了使得這些數值「可比較」(也可以稱為型別的相容性),MySQL會做一些隱式轉化(Implicit type conversion)。那麼什麼是“隱式轉換”呢?讓我們一起來了解一下吧!
當我們對不同型別的值進行比較的時候,為了使得這些數值「可比較」(也可以稱為型別的相容性),MySQL會做一些隱式轉化(Implicit type conversion)。比如下面的例子:
很明顯,上面的SQL語句的執行過程中就出現了隱式轉化。並且從結果們可以判斷出,第一條SQL中,將字串的“1”轉換為數字1,而在第二條的SQL中,將數字2轉換為字串“2”。
MySQL也提供了
CAST()函式。我們可以使用它明確的把數值轉換為字串。當使用CONCA()函式的時候,也可能會出現隱式轉化,因為它希望的引數為字串形式,但是如果我們傳遞的不是字串呢:
隱式轉化規則
官方文件中關於隱式轉化的規則是如下描述的:
- 1.兩個引數至少有一個是 NULL 時,比較的結果也是 NULL,例外是使用 <=> 對兩個 NULL 做比較時會返回 1,這兩種情況都不需要做型別轉換
- 2.兩個引數都是字串,會按照字串來比較,不做型別轉換
- 3.兩個引數都是整數,按照整數來比較,不做型別轉換
- 4.十六進位制的值和非數字做比較時,會被當做二進位制串
- 5.有一個引數是 TIMESTAMP 或 DATETIME,並且另外一個引數是常量,常量會被轉換為 timestamp
- 6.有一個引數是 decimal 型別,如果另外一個引數是 decimal 或者整數,會將整數轉換為 decimal 後進行比較,如果另外一個引數是浮點數,則會把 decimal 轉換為浮點數進行比較
- 7.所有其他情況下,兩個引數都會被轉換為浮點數再進行比較
注意點
安全問題:假如 password 型別為字串,查詢條件為 int 0 則會匹配上。
相信上面的例子,一些機靈的同學可以發現其實上面的例子也可以做sql注入。
假設網站的登入那塊做的比較挫,使用下面的方式:
如果username輸入的是a' OR 1='1,那麼password隨便輸入,這樣就生成了下面的查詢:
就有可能登入系統。其實如果攻擊者看過了這篇文章,那麼就可以利用隱式轉化來進行登入了。如下:
之所以出現上述的原因是因為:
下面透過一些例子來複習一下上面的轉換規則:
把字串“aa”和1進行求和,得到1,因為“aa”和數字1的型別不同,MySQL官方文件告訴我們:
檢視warnings可以看到隱式轉化把字串轉為了double型別。但是因為字串是非數字型的,所以就會被轉換為0,因此最終計算的是0+1=1
上面的例子是型別不同,所以出現了隱式轉化,那麼如果我們使用相同型別的值進行運算呢?
之所以出現這種情況,是因為 “
+” 為算術運算子arithmetic operator 這樣就可以解釋為什麼a和b都轉換為double了。因為轉換之後其實就是:0+0=0了。
在看一個例子:
現在就看也很好的理解上面的例子了吧。
a+b=c結果為1,1在MySQL中可以理解為TRUE,因為
'a'+'b'的結果為0,
c也會隱式轉化為0,因此比較其實是:
0=0也就是true,也就是1.
第二個需要注意點就是防止多查詢或者刪除資料
上面的例子本意是查詢id為5的那一條記錄,結果把id為6的那一條也查詢出來了。我想說明什麼情況呢?有時候我們的資料庫表中的一些列是varchar型別,但是儲存的值為‘1123’這種的純數字的字串值,一些同學寫sql的時候又不習慣加引號。這樣當進行select,update或者delete的時候就可能會多操作一些資料。所以應該加引號的地方別忘記了。
關於字串轉數字的一些說明
- 1.如果字串的第一個字元就是非數字的字元,那麼轉換為數字就是0
- 2.如果字串以數字開頭
- (1)如果字串中都是數字,那麼轉換為數字就是整個字串對應的數字
- (2)如果字串中存在非數字,那麼轉換為的數字就是開頭的那些數字對應的值
來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/69981174/viewspace-2710814/,如需轉載,請註明出處,否則將追究法律責任。
相關文章
- mysql隱式轉換問題MySql
- MySQL索引失效之隱式轉換MySql索引
- 瞭解GaussDB效能調優之隱式轉換,解決慢SQL問題SQL
- 評“MySQL 隱式轉換引起的執行結果錯誤”MySql
- java隱式轉換Java
- javascript 隱式轉換JavaScript
- sql隱式轉換SQL
- 深入瞭解MySQL的索引MySql索引
- js顯式轉換和隱式轉換JS
- [] == ![],走進==隱式轉換的世界
- Scala Essentials: 隱式轉換
- [20191106]隱式轉換.txt
- Spark中的三種隱式轉換Spark
- Java資料型別的顯式轉換和隱式轉換Java資料型別
- JavaScript隱式型別轉換JavaScript型別
- 【C++】禁止隱式轉換C++
- 1 元件化的瞭解元件化
- 深入瞭解SCN(轉)
- 對函式的初步瞭解函式
- C語言的隱式型別轉換C語言型別
- [20220811]奇怪的隱式轉換問題.txt
- mysql 字串和數字比,字串會隱式轉換為數字0MySql字串
- 建構函式定義的隱式型別轉換函式型別
- 瞭解使用mysql 的檢視、儲存過程、觸發器、函式....MySql儲存過程觸發器函式
- JS隱式轉換--寬鬆相等(==)JS
- [譯]隱式轉型,你值得掌握
- 瞭解Android Matrix轉換Android
- 瞭解MySQL的第一步MySql
- Cris 的 Scala 筆記整理(十):隱式轉換筆記
- c++隱式型別轉換存在的陷阱C++型別
- 瞭解JavaScript中的型別轉換JavaScript型別
- vue、react隱式例項化VueReact
- 轉MySQL--mysql常用函式打全MySql函式
- JavaScript 隱式資料型別轉換JavaScript資料型別
- oracle資料隱式轉換規則Oracle
- 如何實現隱式型別轉換型別
- 淺談MySql整型索引和字串索引失效或隱式轉換問題汊叄MySql索引字串
- 深入瞭解 iOS 的初始化iOS