Sửa lỗi MySQL ERROR 1064: You have an error in your SQL syntax

beginner🗄️ MySQL2026-03-21| MySQL 5.7, 8.0 / MariaDB / Linux, macOS, Windows / MySQL CLI, phpMyAdmin, DBeaver

Error Message

ERROR 1064 (42000): You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near '...' at line 1
#mysql#sql#lỗi-cú-pháp#truy-vấn#debug

Chuyện gì đang xảy ra

Câu truy vấn của bạn không chạy được. MySQL ném ra ERROR 1064 (42000): You have an error in your SQL syntax — cách MySQL nói rằng "tôi không thể phân tích cú pháp câu lệnh này." Có gì đó trong câu lệnh của bạn đã vi phạm các quy tắc ngữ pháp mà trình phân tích cú pháp MySQL yêu cầu.

Một điều hay gây nhầm lẫn: lỗi chỉ đến vị trí sau khi MySQL bị rối, không phải nơi có lỗi thực sự. Vì vậy "near '...' at line 1" chỉ là gợi ý, không phải lời thú nhận. Thủ phạm thực sự thường nằm ở token ngay trước đó.

Các tình huống phổ biến gây ra ERROR 1064

  • Dùng từ khóa dành riêng làm tên bảng hoặc tên cột mà không có backtick
  • Thiếu hoặc đặt sai vị trí dấu phẩy, dấu ngoặc đơn, hoặc dấu nháy
  • Sai kiểu dấu nháy — dấu nháy cong từ Word hoặc Google Docs thay vì dấu nháy thẳng
  • Chạy cú pháp MySQL 8.0 trên server 5.7 (hoặc ngược lại)
  • Dán SQL từ trình soạn thảo văn bản có chứa ký tự Unicode ẩn
  • Quên từ khóa SET trong câu lệnh UPDATE
  • Dư hoặc thiếu dấu chấm phẩy bên trong stored procedure

Cách sửa nhanh theo từng nguyên nhân

1. Dùng từ khóa dành riêng làm định danh

Đây là nguyên nhân số 1. Các tên như order, key, value, rank, group, desc, và status là các từ khóa dành riêng. MySQL sẽ báo lỗi ngay khi chúng xuất hiện mà không được bọc trong backtick.

-- Lỗi
SELECT order, status FROM users;

-- Đã sửa: bọc các từ khóa dành riêng trong backtick
SELECT `order`, `status` FROM users;

Danh sách đầy đủ có tại MySQL 8.0 Reserved Words. Nên đánh dấu trang để tham khảo.

2. Dấu nháy không khớp hoặc bị thiếu

-- Lỗi: thiếu dấu nháy đóng
SELECT * FROM products WHERE name = 'Widget;

-- Lỗi: dấu nháy cong được sao chép từ trình soạn thảo văn bản
SELECT * FROM products WHERE name = 'Widget';

-- Đã sửa
SELECT * FROM products WHERE name = 'Widget';

Sao chép SQL từ PDF hoặc tài liệu? Hãy gõ lại dấu nháy bằng tay trong terminal. Dấu nháy cong trông giống hệt trên màn hình nhưng thực chất là ký tự hoàn toàn khác.

3. Thiếu dấu phẩy giữa các cột

-- Lỗi
SELECT id name email FROM users;

-- Đã sửa
SELECT id, name, email FROM users;

4. Sai cú pháp UPDATE — thiếu SET

-- Lỗi
UPDATE users name = 'Alice' WHERE id = 1;

-- Đã sửa
UPDATE users SET name = 'Alice' WHERE id = 1;

5. INSERT sai cấu trúc dấu ngoặc đơn

-- Lỗi
INSERT INTO users (id, name) VALUES 1, 'Alice';

-- Đã sửa
INSERT INTO users (id, name) VALUES (1, 'Alice');

6. Dùng window function của MySQL 8.0 trên MySQL 5.7

-- Lỗi trên MySQL 5.7 — không hỗ trợ window function
SELECT id, ROW_NUMBER() OVER (PARTITION BY dept_id ORDER BY salary DESC) AS rn
FROM employees;

-- Kiểm tra phiên bản server trước
SELECT VERSION();

Đang dùng 5.7 mà cần window function? Hãy nâng cấp lên MySQL 8.0 hoặc viết lại logic bằng subquery.

7. Stored procedure thiếu thay đổi DELIMITER

MySQL CLI xử lý ; là ký hiệu kết thúc lệnh. Gặp dấu này trong thân procedure, CLI sẽ gửi ngay một câu lệnh không đầy đủ.

-- Lỗi: CLI kích hoạt ngay tại dấu ; đầu tiên
CREATE PROCEDURE get_users()
BEGIN
  SELECT * FROM users;
END;

-- Đã sửa
DELIMITER //
CREATE PROCEDURE get_users()
BEGIN
  SELECT * FROM users;
END //
DELIMITER ;

Cách debug

Khi thông báo lỗi không rõ ràng, hãy thu hẹp vấn đề từng bước một.

Bước 1 — Đọc gợi ý "near" một cách trực tiếp

MySQL hiển thị token nơi nó bỏ cuộc. Lỗi thực sự hầu như luôn nằm ngay trước token đó.

ERROR 1064 (42000): ... near 'WHERE id = 1' at line 1

Trình phân tích cú pháp bị lỗi tại WHERE. Điều này chỉ về mệnh đề trước đó — mệnh đề SET có thể bị sai cú pháp.

Bước 2 — Rút gọn truy vấn xuống mức tối thiểu

Xóa mọi thứ trừ phần khung cơ bản. Thêm dần từng mệnh đề cho đến khi lỗi xuất hiện trở lại. Phần thêm cuối cùng gây ra lỗi chính là thủ phạm.

-- Bắt đầu từ đây
SELECT * FROM users;

-- Thêm WHERE
SELECT * FROM users WHERE id = 1;

-- Thêm phần còn lại
SELECT * FROM users WHERE id = 1 ORDER BY name;

Bước 3 — Tìm ký tự ẩn

SQL được dán từ trình duyệt hoặc trình soạn thảo văn bản thường mang theo Unicode ẩn — zero-width space, non-breaking space, ký tự xuống dòng kiểu Windows. Không cái nào nhìn thấy được nhưng tất cả đều phá vỡ trình phân tích cú pháp.

cat -A query.sql | head -5
# Tìm ^M (ký tự xuống dòng Windows) hoặc các ký tự bất thường khác

Hoặc mở file trong vim và chạy :set list để hiển thị tất cả ký tự ẩn.

Bước 4 — Kiểm tra cú pháp mà không thực thi

# MySQL CLI: phát hiện lỗi cú pháp qua EXPLAIN
mysql -u root -p -e "EXPLAIN SELECT * FROM users WHERE id = 1"

# Hoặc kiểm tra toàn bộ database với mysqlcheck
mysqlcheck -u root -p --check mydb

Ngăn lỗi tái diễn

Luôn dùng backtick cho tên bảng và tên cột khi không chắc chắn

CREATE TABLE `order` (
  `id` INT PRIMARY KEY,
  `status` VARCHAR(50),
  `value` DECIMAL(10,2)
);

Dùng SQL linter trong trình soạn thảo

Các extension như SQLTools (VS Code) hoặc sql-language-server đánh dấu lỗi cú pháp trước khi bạn nhấn chạy. Phát hiện lỗi ngay lúc viết, không phải lúc chạy thật.

Dùng parameterized query trong code ứng dụng

Xây dựng SQL bằng cách nối chuỗi là nguồn gốc của cả lỗi injection lẫn lỗi cú pháp. Prepared statement loại bỏ cả hai vấn đề cùng một lúc:

# Python (mysql-connector)
cursor.execute("SELECT * FROM users WHERE id = %s", (user_id,))
// Node.js (mysql2)
connection.execute('SELECT * FROM users WHERE id = ?', [userId])

Xác nhận đã sửa xong

Chạy lại truy vấn. Kết quả trả về hoặc Query OK, N rows affected nghĩa là lỗi cú pháp đã được khắc phục.

-- Với SELECT
SELECT id, name FROM users WHERE id = 1;
-- Kết quả mong đợi: 1 hàng được trả về

-- Với INSERT/UPDATE/DELETE
UPDATE users SET name = 'Alice' WHERE id = 1;
-- Kết quả mong đợi: Query OK, 1 row affected

Đã sửa stored procedure? Gọi nó ngay sau khi tạo để xác nhận chạy được từ đầu đến cuối:

CALL get_users();

Related Error Notes