Nỗi lo khi di chuyển dữ liệuĐây là một tình huống kinh điển: ứng dụng cũ của bạn chạy hoàn hảo trên máy chủ cũ nhưng lại gặp lỗi ngay lập tức trên phiên bản MySQL 8.0 mới. Lỗi này thường xuất hiện khi chuyển đổi các mã nguồn PHP 5.6 hoặc Python 2.7 sang các stack công nghệ hiện đại. Mặc dù mã nguồn đã hoạt động ổn định trong nhiều năm, các truy vấn INSERT hoặc UPDATE của bạn giờ đây lại vấp phải thông báo lỗi này:
ERROR 1366 (HY000): Incorrect integer value: '' for column 'id' at row 1
Nguồn gốc của vấn đề rất đơn giản. Ứng dụng của bạn đang cố gắng lưu một chuỗi trống ('') vào một cột kiểu INT hoặc BIGINT. Các phiên bản MySQL cũ hơn thường dễ dãi hơn; chúng sẽ nhận chuỗi trống và âm thầm chuyển đổi nó thành 0. Các phiên bản hiện đại từ chối việc tự ý phỏng đoán này.
Nguyên nhân: Chế độ Strict ModeHành vi này bắt nguồn từ một cài đặt có tên là STRICT_TRANS_TABLES. Kể từ MySQL 5.7.5, chế độ strict mode đã được bật theo mặc định. Khi được kích hoạt, cơ sở dữ liệu sẽ ngừng thực hiện "chuyển đổi dữ liệu ngầm định" có thể dẫn đến mất mát dữ liệu. Vì một chuỗi trống không phải là một con số hợp lệ, MySQL sẽ đưa ra một lỗi nghiêm trọng thay vì chỉ là một cảnh báo.
Kiểm tra cấu hình hiện tại của bạn bằng một truy vấn nhanh trong terminal MySQL:
SELECT @@sql_mode;
Nếu kết quả bao gồm STRICT_TRANS_TABLES hoặc STRICT_ALL_TABLES, cơ sở dữ liệu đang thực thi quy tắc nghiêm ngặt về kiểu dữ liệu.
Giải pháp 1: Sửa Logic ứng dụng (Cách làm đúng đắn)Đây là giải pháp bền vững và mạnh mẽ nhất về lâu dài. Nếu một trường số là tùy chọn (không bắt buộc), mã nguồn của bạn nên gửi giá trị NULL hoặc giá trị 0 thực tế thay vì một chuỗi trống.
Ví dụ trong PHPTránh truyền trực tiếp dữ liệu thô chưa qua kiểm duyệt vào các chuỗi SQL. Nếu giá trị POST trống, hãy đặt nó thành NULL một cách rõ ràng:
// Thay vì gửi một chuỗi trống...
$age = ($_POST['age'] === '') ? "NULL" : (int)$_POST['age'];
$sql = "INSERT INTO users (age) VALUES ($age)";
Cách tiếp cận SQL chuẩnCấu trúc lại các truy vấn thủ công của bạn để đảm bảo chúng tuân theo các mẫu sau:
-- Câu lệnh này sẽ thất bại trong strict mode
INSERT INTO products (stock) VALUES ('');
-- Những câu lệnh này sẽ thành công
INSERT INTO products (stock) VALUES (NULL);
INSERT INTO products (stock) VALUES (0);
Giải pháp 2: Khắc phục nhanh: Thay đổi ở cấp độ SessionNếu bạn đang trong tình huống khẩn cấp và cần ứng dụng hoạt động ngay lập tức, bạn có thể nới lỏng các quy tắc cho kết nối cơ sở dữ liệu hiện tại. Đây là phương pháp tạm thời cho các script cũ trong khi bạn tìm cách sửa mã nguồn vĩnh viễn.
Thực thi truy vấn này ngay sau khi ứng dụng của bạn thiết lập kết nối cơ sở dữ liệu:
SET SESSION sql_mode = 'NO_ENGINE_SUBSTITUTION';
Bằng cách loại bỏ các cờ strict mode, MySQL sẽ quay lại hành vi cũ, chuyển đổi các chuỗi trống thành 0 trong khi vẫn đưa ra một cảnh báo nhỏ ở chế độ nền.
Giải pháp 3: Điều chỉnh vĩnh viễn trên toàn hệ thốngNếu bạn quản lý hạ tầng và cần hỗ trợ một hệ thống CMS hoặc ERP cũ không dễ dàng vá lỗi, bạn có thể tắt strict mode trên toàn cầu.
Trên Linux (Ubuntu/Debian)- Mở tệp cấu hình của bạn: sudo nano /etc/mysql/mysql.conf.d/mysqld.cnf.- Tìm khối [mysqld].- Thêm hoặc cập nhật định nghĩa sql_mode:```
[mysqld]
sql_mode = "NO_ENGINE_SUBSTITUTION"
```- Khởi động lại dịch vụ để áp dụng thay đổi: sudo systemctl restart mysql### Trên Windows (XAMPP)- Mở XAMPP Control Panel và nhấn vào Config bên cạnh MySQL.- Chọn my.ini từ danh sách.- Tìm dòng sql-mode và đổi thành sql-mode="NO_ENGINE_SUBSTITUTION".- Khởi động lại module MySQL.## Xác minhLuôn xác minh các thay đổi. Kiểm tra biến toàn cục trước:
SELECT @@GLOBAL.sql_mode;
Xác nhận rằng STRICT_TRANS_TABLES đã biến mất. Cuối cùng, chạy một bài kiểm tra thủ công để đảm bảo lỗi đã được giải quyết:
INSERT INTO your_table (your_int_column) VALUES ('');
Nếu bạn thấy thông báo "1 row affected" kèm theo một cảnh báo, việc sửa lỗi đã thành công. Bạn có thể chạy SHOW WARNINGS; để xem chính xác cách MySQL xử lý việc chuyển đổi.

