一.問題重現
1.問題模擬
🌰舉例
一個person表,假設其中有sex性別欄位型別為varchar,0代表女,1代表男,建表如下
CREATE TABLE `person` ( `id` bigint(20) NOT NULL COMMENT 'id', `name` varchar(255) NOT NULL COMMENT '名稱', `age` int(10) NOT NULL COMMENT '年齡', `sex` varchar(2) CHARACTER SET utf8 COLLATE utf8_general_ci DEFAULT NULL COMMENT '性別(男;女)', PRIMARY KEY (`id`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8;
插入模擬資料
INSERT INTO `demo`.`person` (`id`, `name`, `age`, `sex`) VALUES (1, '張三', 20, '男'); INSERT INTO `demo`.`person` (`id`, `name`, `age`, `sex`) VALUES (2, '李四', 30, '女'); INSERT INTO `demo`.`person` (`id`, `name`, `age`, `sex`) VALUES (3, '小姐姐', 18, '0'); INSERT INTO `demo`.`person` (`id`, `name`, `age`, `sex`) VALUES (4, '王五', 20, '男');
2.查詢語句
現在我們要查詢性別為0的問題資料
SELECT * FROM person WHERE sex = 0;
執行結果
結果是不是出人意料,竟然將所有資料都查出,是不是失效出bug了?
其實這就是MySQL的隱式特性,而不是什麼bug,別急後面慢慢詳解...
二.MySQL隱式轉換
1.隱式轉換是什麼?
MySQL中的隱式型別轉換是指當執行某些操作時,如比較操作或其他需要特定資料型別引數的操作時,如果參與操作的表示式或列的資料型別不匹配,MySQL將會自動進行資料型別轉換以適應預期的資料型別。
👽人話解釋
就是欄位型別不匹配,mysql會自動轉,如果你以數字0為條件,mysql就會將欄位內容轉成數字進行處理
2.示例問題分析
在MySQL中,當你嘗試用整數 0 作為條件去查詢一個 VARCHAR 型別的欄位時,MySQL 會嘗試將 VARCHAR 欄位的內容轉換為數字進行比較。
這種情況下,MySQL 會檢查字串的開始部分是否可以解析為一個數字。如果可以,它將使用這個數字值進行比較;如果不能解析為數字,則預設使用 0 進行比較。
也就是說
SELECT * FROM person WHERE sex = 0; 和 SELECT * FROM person WHERE sex = '0';
兩個表達的意思完全不一樣,用0會查到所有非數字開頭的字串,用其他數字查則會匹配到與之對應數字開頭的字串
總結
1.問題重現:
建立 person 表,sex 欄位為 VARCHAR 型別。
插入資料,包括 sex 為 '男'、'女'、'0' 等。
查詢 SELECT * FROM person WHERE sex = 0; 返回所有資料,而非僅 '0'。
2.原因分析:
MySQL 嘗試將 VARCHAR 欄位內容轉換為數字進行比較。
如果字串可以解析為數字,則使用該數字;否則預設使用 0。
3.解決方法:
顯式型別轉換:SELECT * FROM person WHERE CAST(sex AS SIGNED) = 0;
直接使用字串比較:SELECT * FROM person WHERE sex = '0';
4.結論
隱式轉換會導致意外結果:使用整數 0 查詢 VARCHAR 欄位時,MySQL 會嘗試將字串轉換為數字。
顯式型別轉換更安全:顯式地進行型別轉換可以確保查詢結果符合預期。