Vấn đề: Sắp xếp động bằng biến số
Cần thực hiện ORDER BY với tên cột được xác định tại runtime thông qua biến người dùng (@variable). MySQL không cho phép đặt tên cột trực tiếp bằng biến trong câu lệnh thông thường.
Giải pháp: Prepared Statement động
Xây dựng chuỗi SQL động, chuẩn bị (PREPARE), thực thi (EXECUTE), rồi giải phóng (DEALLOCATE PREPARE).
1. Tạo bảng và dữ liệu
CREATE TABLE DemoTable (Number INT);
INSERT INTO DemoTable VALUES (10), (70), (30), (50), (40);
2. Quy trình thực thi
-- 1. Gán giá trị cho biến (ví dụ: sắp xếp theo cột thứ 1)
SET @limitValue := 1;
-- 2. Xây dựng câu SQL động
SET @query := CONCAT('SELECT * FROM DemoTable ORDER BY ', @limitValue);
-- 3. Chuẩn bị statement
PREPARE stmt FROM @query;
-- 4. Thực thi
EXECUTE stmt;
-- 5. Giải phóng
DEALLOCATE PREPARE stmt;
3. Kết quả (sắp xếp theo cột 1 - Number)
+--------+
| Number |
+--------+
| 10 |
| 30 |
| 40 |
| 50 |
| 70 |
+--------+
Giải thích
@limitValue := 1– Biến lưu vị trí cột (1 = cột đầu tiên trong SELECT).CONCAT– Ghép chuỗi SQL động.PREPARE– Biên dịch câu SQL từ chuỗi.EXECUTE– Chạy câu lệnh đã chuẩn bị.DEALLOCATE PREPARE– Giải phóng bộ nhớ.
Ứng dụng thực tế
Dùng trong stored procedure khi tên cột sắp xếp do người dùng chọn (ví dụ: API cho phép sắp xếp theo 'name', 'age', 'date'). Cần validate tên cột để tránh SQL Injection.
Cảnh báo bảo mật
Không bao giờ nối trực tiếp input người dùng vào chuỗi SQL động. Luôn kiểm tra whitelist tên cột cho phép:
SET @col = CASE @userInput
WHEN 'name' THEN 'FirstName'
WHEN 'age' THEN 'Age'
ELSE 'Id' END;
SET @query = CONCAT('SELECT * FROM Users ORDER BY ', @col);