MySQL中字符串與數字比較的坑


公司項目代碼中,某枚舉字段數據庫表中類型是char(1),在代碼中,誤以為是TINYINT,所以用數字篩選,后來發現結果不對。發現了一個現象,用數字0篩選會把所有的記錄給篩選出來。
經過排查發現是在MySQL查詢語句中,'abc'如果和'0'比較結果顯然是不等的,但如果'abc'和0比較呢?結果居然是相等的。

隨意測試了幾下,結果如下:

mysql> select 'abc'=0;
+---------+
| 'abc'=0 |
+---------+
|       1 |
+---------+
1 row in set, 1 warning (0.00 sec)
mysql> select '0abc'=0;
+----------+
| '0abc'=0 |
+----------+
|        1 |
+----------+
1 row in set, 1 warning (0.00 sec)
mysql> select '01abc'=0;
+-----------+
| '01abc'=0 |
+-----------+
|         0 |
+-----------+
1 row in set, 1 warning (0.00 sec)
mysql> select '013abc'=13;
+-------------+
| '013abc'=13 |
+-------------+
|           1 |
+-------------+
1 row in set, 1 warning (0.00 sec)

以上幾個查詢通過查看MySQL給出的警告,都可以看到類似如下的信息

mysql> show warnings;
+---------+------+--------------------------------------------+
| Level   | Code | Message                                    |
+---------+------+--------------------------------------------+
| Warning | 1292 | Truncated incorrect DOUBLE value: '013abc' |
+---------+------+--------------------------------------------+
1 row in set (0.00 sec)

查閱MySQL 5.7官方文檔中關於比較的章節,其中說明Strings are automatically converted to numbers and numbers to strings as necessary.。也就是說在比較的時候,String是可能會被轉為數字的。

而對於數字開頭的字符串來說,轉為數字的結果就是截取前面的數字部分

mysql> select cast('123abc' as signed);
+-----------------------------+
| cast('123abc' as signed) |
+-----------------------------+
|                         123 |
+-----------------------------+
1 row in set, 1 warning (0.00 sec)
mysql> select cast('123.45abc' as decimal(5,2));
+-----------------------------------+
| cast('123.45abc' as decimal(5,2)) |
+-----------------------------------+
|                            123.45 |
+-----------------------------------+
1 row in set (0.00 sec)
mysql> select cast('abc' as signed);
+-----------------------+
| cast('abc' as signed) |
+-----------------------+
|                     0 |
+-----------------------+
1 row in set, 1 warning (0.00 sec)

而對於開頭部分不能截取出數字的字符串來說,轉換的結果自然就是0了。

關於字符串類型與整數直接進行比較的坑,說穿了就是MySQL中字符串轉為數字的邏輯,沒遇到過確實可能不太清楚,遇到過一次以后經驗就是,看清楚數據庫表字段,盡量避免字符串與數字的直接比較。

此外,書寫sql語句的時候務必注意不要犯類型的錯誤,也許查出來的結果是對的,但是由於類型不匹配的原因,將會導致表索引無法用上


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM