การใช้ Prepared Statement ใน Stored Procedure เพื่อกำหนดค่าตัวแปร
ใช้ PREPARE, EXECUTE, DEALLOCATE PREPARE ภายใน Stored Procedure เพื่อสร้าง Dynamic SQL และเก็บผลลัพธ์ใน User Variable (@var)
ตัวอย่าง Stored Procedure แบบ Dynamic
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 ;
การเรียกใช้และตรวจสอบผลลัพธ์
สร้างตารางและข้อมูลทดสอบ:
mysql> CREATE TABLE DemoTable (Id INT, Name VARCHAR(100)); Query OK, 0 rows affected (1.51 sec) mysql> INSERT INTO DemoTable VALUES (10, 'John'), (11, 'Chris'); Query OK, 2 rows affected
เรียก Procedure:
mysql> CALL Prepared_Statement_Demo('DemoTable', 'Name', 10);
Query OK, 0 rows affected, 2 warnings (0.00 sec)
ตรวจสอบตัวแปร @value:
mysql> SELECT @value;
+--------+ | @value | +--------+ | John | +--------+ 1 row in set (0.00 sec)
คำอธิบายขั้นตอน
CONCAT- สร้าง SQL String แบบ DynamicPREPARE st FROM @sql- Compile StatementEXECUTE st- รัน Statement (ผลลัพธ์จะไปอยู่ในINTO @value)DEALLOCATE PREPARE st- ปล่อยหน่วยความจำ (สำคัญ! ป้องกัน Memory Leak)
ข้อควรระวังด้านความปลอดภัย (SQL Injection)
- ตัวอย่างนี้ **อันตราย** หาก Input มาจาก User โดยไม่ Validate/Sanitize
- ใช้
QUOTE()สำหรับ String:CONCAT('... WHERE name = ', QUOTE(user_input)) - ใช้ Parameterized Query (Prepared Statement แบบ Parameter) แทน Dynamic SQL ถ้าเป็นไปได้
- Validate Table/Column Name ให้อยู่ใน Whitelist
Prepared Statement แบบ Parameterized (ปลอดภัยกว่า)
PREPARE stmt FROM 'SELECT name FROM DemoTable WHERE id = ?'; SET @id = 10; EXECUTE stmt USING @id; DEALLOCATE PREPARE stmt;