Computer >> Hướng Dẫn Máy Tính >  >> Lập Trình >> MySQL

Gán kết quả SQL vào biến từ Prepared Statement trong MySQL?

Gán kết quả truy vấn động vào biến với Prepared Statement trong MySQL

Sử dụng Stored Procedure kết hợp Prepared Statement (PREPARE, EXECUTE, DEALLOCATE PREPARE) để xây dựng truy vấn động và gán kết quả vào biến session (@variable).

Ví dụ minh họa

Tạo bảng DemoTable:

mysql> CREATE TABLE DemoTable (Id INT, Name VARCHAR(100));
Query OK, 0 rows affected (1.51 sec)

Chèn dữ liệu:

mysql> INSERT INTO DemoTable VALUES(10, 'John');
Query OK, 1 row affected (0.17 sec)
mysql> INSERT INTO DemoTable VALUES(11, 'Chris');
Query OK, 1 row affected (0.41 sec)

Xem dữ liệu:

mysql> SELECT * FROM DemoTable;
+------+-------+
| Id   | Name  |
+------+-------+
| 10   | John  |
| 11   | Chris |
+------+-------+
2 rows in set (0.00 sec)

Tạo Stored Procedure nhận tên bảng, tên cột, ID - trả về giá trị vào biến @value:

mysql> DELIMITER //
mysql> CREATE PROCEDURE Prepared_Statement_Demo(
    IN nameOfTable VARCHAR(20),
    IN nameOfColumn VARCHAR(20),
    IN idColumnName INT
)
BEGIN
    SET @holdResult = CONCAT('SELECT ', nameOfColumn, ' INTO @value FROM ', nameOfTable, ' WHERE Id = ', idColumnName);
    PREPARE st FROM @holdResult;
    EXECUTE st;
    DEALLOCATE PREPARE st;
END //
Query OK, 0 rows affected (0.20 sec)
mysql> DELIMITER ;

Gọi Procedure:

mysql> CALL Prepared_Statement_Demo('DemoTable', 'Name', 10);
Query OK, 0 rows affected, 2 warnings (0.00 sec)

Kiểm tra biến @value:

mysql> SELECT @value;
+--------+
| @value |
+--------+
| John   |
+--------+
1 row in set (0.00 sec)

Giải thích quy trình

  1. CONCAT(...): Xây dựng chuỗi SQL động
  2. PREPARE st FROM @holdResult: Biên dịch statement từ chuỗi
  3. EXECUTE st: Thực thi statement đã chuẩn bị
  4. DEALLOCATE PREPARE st: Giải phóng prepared statement
  5. SELECT ... INTO @value: Gán kết quả trực tiếp vào biến session

⚠️ Cảnh báo bảo mật (SQL Injection)

Ví dụ này dễ bị SQL Injection vì nối chuỗi trực tiếp tham số đầu vào. Trong production:

  • Dùng Parameterized Prepared Statement với placeholder ?
  • Validate/whitelist tên bảng, tên cột (không cho user nhập tự do)
  • Hoặc dùng ORM/Query Builder an toàn

Phiên bản an toàn với Parameterized Query

CREATE PROCEDURE Safe_Demo(IN tableName VARCHAR(64), IN colName VARCHAR(64), IN idVal INT)
BEGIN
    -- Whitelist validation
    IF tableName NOT IN ('DemoTable','OtherTable') OR colName NOT IN ('Name','Email') THEN
        SIGNAL SQLSTATE '45000' SET MESSAGE_TEXT = 'Invalid table/column';
    END IF;
    
    SET @sql = CONCAT('SELECT ', colName, ' INTO @result FROM ', tableName, ' WHERE Id = ?');
    PREPARE stmt FROM @sql;
    SET @id = idVal;
    EXECUTE stmt USING @id;
    DEALLOCATE PREPARE stmt;
END