การเก็บค่าเก่าก่อนอัปเดตด้วย User-Defined Variable
ใน Stored Procedure หากต้องการเก็บค่าเดิมของฟิลด์ไว้ก่อนทำการ UPDATE แล้วนำค่าเก้าไปใช้งานต่อ (เช่น บันทึก Log, คำนวณความแตกต่าง) ควรอ่านค่ามาเก็บในตัวแปร ก่อน คำสั่ง UPDATE
ตัวอย่างสร้างตารางและข้อมูล
CREATE TABLE DemoTable (
Id INT NOT NULL AUTO_INCREMENT PRIMARY KEY,
Value INT
);
INSERT INTO DemoTable (Value) VALUES (100);
Stored Procedure ที่เก็บค่าเก่าถูกต้อง
DELIMITER //
CREATE PROCEDURE UpdateValueKeepOld()
BEGIN
DECLARE oldValue INT;
-- 1. อ่านค่าเก่ามาเก็บในตัวแปร LOCAL ก่อน
SELECT Value INTO oldValue FROM DemoTable WHERE Id = 1;
-- 2. แสดงค่าเก่า (ยังไม่เปลี่ยน)
SELECT oldValue AS OldValue;
-- 3. ทำการ UPDATE
UPDATE DemoTable SET Value = 200 WHERE Id = 1;
-- 4. อ่านค่าใหม่มาเก็บในตัวแปรอีกตัว
DECLARE newValue INT;
SELECT Value INTO newValue FROM DemoTable WHERE Id = 1;
-- 5. แสดงค่าใหม่
SELECT newValue AS NewValue;
-- 6. สามารถคำนวณความต่างได้
SELECT (newValue - oldValue) AS Difference;
END //
DELIMITER ;
เรียกใช้ Stored Procedure
CALL UpdateValueKeepOld();
ผลลัพธ์
+----------+ | OldValue | +----------+ | 100 | +----------+ +-----------+ | NewValue | +-----------+ | 200 | +-----------+ +------------+ | Difference | +------------+ | 100 | +------------+
จุดสำคัญ:
- ใช้
DECLAREสร้างตัวแปร LOCAL (มีขอบเขตใน Procedure) แทน User-Defined Variable (@var) ที่คงค่าตลอด Session - ใช้
SELECT ... INTO varเพื่ออ่านค่าจากตารางมาเก็บในตัวแปร - ลำดับคำสั่ง: อ่านค่าเก่า → UPDATE → อ่านค่าใหม่
- ตัวอย่างในคำถามเดิมใช้ @myValue ซึ่งเป็น Session Variable จะคงค่าเดิมได้แค่ตอนอ่านครั้งแรก แต่หลัง UPDATE แล้วอ่านใหม่จะได้ค่าใหม่ทับทีหลัง
แนวทางปฏิบัติที่ดี (Best Practice): ควรใช้ Transaction หากต้องการความสมบูรณ์ของข้อมูล (Atomicity) ระหว่างอ่านค่าเก่าและอัปเดตค่าใหม่