執行 UPDATE 或 INSERT 中文時拋出 1366 Incorrect string value: '\xE8\x82\x96\xE5\xB1\xB1...' for column 'xxx',意味著**該欄位編碼無法容納輸入的字元位元組序列**。本文提供四層檢查清單與一鍵修復腳本。
\xE8\x82\x96\xE5\xB1\xB1 = UTF-8 編碼的「肝山」latin1 或 gbk,無法儲存該 UTF-8 字元latin1,導致伺服端誤判輸入編碼-- 檢查
SHOW CREATE DATABASE db_name;
-- 修正
ALTER DATABASE db_name CHARACTER SET = utf8mb4 COLLATE = utf8mb4_unicode_ci;
-- 檢查
SHOW CREATE TABLE tbl_name;
-- 修正 (僅影響新建欄位)
ALTER TABLE tbl_name CHARACTER SET = utf8mb4 COLLATE = utf8mb4_unicode_ci;
-- 連帶修正現有欄位
ALTER TABLE tbl_name CONVERT TO CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
-- 檢查
SHOW FULL COLUMNS FROM tbl_name;
-- 修正單一欄位
ALTER TABLE tbl_name MODIFY col_name VARCHAR(100) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
-- 或使用 CONVERT TO 批次修正全表欄位
-- 檢查當前連線
SHOW VARIABLES LIKE 'character_set_%';
-- JDBC 連線字串 (關鍵!)
jdbc:mysql://host:3306/db?useUnicode=true&characterEncoding=utf8mb4&zeroDateTimeBehavior=convertToNull
-- PHP PDO
$dsn = "mysql:host=localhost;dbname=db;charset=utf8mb4";
-- Python PyMySQL
conn = pymysql.connect(charset='utf8mb4')
-- 通用會話級修正
SET NAMES utf8mb4;
-- 1. 修正資料庫
ALTER DATABASE `your_db` CHARACTER SET = utf8mb4 COLLATE = utf8mb4_unicode_ci;
-- 2. 修正所有表 (含欄位轉換)
SELECT CONCAT('ALTER TABLE `', TABLE_SCHEMA, '`.`', TABLE_NAME, '` CONVERT TO CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;')
FROM information_schema.TABLES
WHERE TABLE_SCHEMA = 'your_db'
INTO OUTFILE '/tmp/fix_charset.sql';
-- 3. 執行生成的 SQL
SOURCE /tmp/fix_charset.sql;
-- 測試插入中文
INSERT INTO test_tbl (col) VALUES ('測試肝山😀');
SELECT * FROM test_tbl;
| 現象 | 原因 | 解決 |
|---|---|---|
| 修正後仍報 1366 | 連線字串未加 characterEncoding | 檢查應用配置、連線池屬性 |
| 歷史資料變亂碼 | 原資料以錯誤編碼寫入 (雙重編碼) | 需程式碼層面清洗重寫,或接受遺失 |
| Emoji 存入變 ???? | 仍用 utf8 (utf8mb3) | 全鏈路升級 utf8mb4 |
核心口訣: **Schema/Table/Column/Connection 四層皆為 utf8mb4**,少一層皆可能 1366。連線字串 characterEncoding=utf8mb4 是「最後一公里」,最易漏、最關鍵。