MySQL字串與數比較的大坑
阿新 • • 發佈:2020-12-23
技術標籤:java
MySQL字串與數字比較的大坑
前言
一次查詢資料時,發現取到的資料是錯亂的
對一下進行測試
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語句的時候務必注意不要犯型別的錯誤,也許查出來的結果是對的,但是由於型別不匹配的原因,將會導致表索引無法用上。