首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫

MySQL DATE_FORMAT() 字元集陷阱:與 TIMEDIFF() 比較報錯的根因與解法

     編輯:MySQL 資料庫相關知識

執行 SELECT DATE_FORMAT(...) > TIMEDIFF(...) 報錯 Illegal mix of collations (utf8_general_ci,COERCIBLE) and (latin1_swedish_ci,NUMERIC)。根因:DATE_FORMAT() 回傳帶有連線字元集/校對集屬性的字串,而 TIMEDIFF() 回傳二進位字串(無字元集),兩者直接比較觸發校對集衝突。

驗證字元集差異

mysql> SET NAMES utf8;
mysql> SELECT CHARSET(DATE_FORMAT('2013-11-19','%Y-%m-%d')), CHARSET(TIMEDIFF('2013-11-19', '2013-11-20'));
+---------------------------------------------------+--------------------------------------------------+
| CHARSET(DATE_FORMAT('2013-11-19','%Y-%m-%d'))     | CHARSET(TIMEDIFF('2013-11-19', '2013-11-20'))   |
+---------------------------------------------------+--------------------------------------------------+
| utf8                                              | binary                                           |
+---------------------------------------------------+--------------------------------------------------+

mysql> SET NAMES gb2312;
mysql> SELECT CHARSET(DATE_FORMAT('2013-11-19','%Y-%m-%d')), CHARSET(TIMEDIFF('2013-11-19', '2013-11-20'));
+---------------------------------------------------+--------------------------------------------------+
| CHARSET(DATE_FORMAT('2013-11-19','%Y-%m-%d'))     | CHARSET(TIMEDIFF('2013-11-19', '2013-11-20'))   |
+---------------------------------------------------+--------------------------------------------------+
| gb2312                                            | binary                                           |
+---------------------------------------------------+--------------------------------------------------+

DATE_FORMAT() 的字元集隨 character_set_connection/collation_connection 變化;TIMEDIFF() 永遠回傳 binary。

解決方案:顯式轉換字元集

SELECT DATE_FORMAT('2013-11-19','%Y-%m-%d') 
       > CONVERT(TIMEDIFF('2013-11-19', '2013-11-20') USING utf8);

或統一轉為 binary:

SELECT CONVERT(DATE_FORMAT('2013-11-19','%Y-%m-%d') USING binary) 
       > TIMEDIFF('2013-11-19', '2013-11-20');

最佳實務

  • 避免不同字元集函式回傳值直接比較/連接。
  • 使用 CONVERT(... USING charset) 或 CAST(... AS BINARY) 顯式統一。
  • 應用層統一設定 SET NAMES utf8mb4,減少隱含轉換驚喜。
  • 注意:DATE_FORMAT 格式字串用 %Y-%m-%d(非 Y-m-d),原文範例格式錯誤已修正。
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved