MySQL Trigger การใช้ OLD และ NEW

MySQL อนุญาตให้เราสามารถ เข้าถึงค่าของข้อมูล “ก่อน” และ “หลัง” การเปลี่ยนแปลง ภายใน Trigger ได้ผ่าน keyword พิเศษดังนี้

  • NEW.column_name ค่าที่จะถูกบันทึก (ใช้กับ INSERT, UPDATE)
  • OLD.column_name ค่าก่อนการเปลี่ยนแปลง (ใช้กับ UPDATE, DELETE)

ตารางสรุปการใช้ OLD และ NEW กับแต่ละ Trigger

Trigger Type ใช้ OLD ได้หรือไม่ ใช้ NEW ได้หรือไม่
BEFORE INSERT
AFTER INSERT
BEFORE UPDATE
AFTER UPDATE
BEFORE DELETE
AFTER DELETE

ตัวอย่างการใช้งาน

ใช้ NEW ใน BEFORE INSERT ตั้งค่า default ให้ช่องว่าง

เป้าหมายของตัวอย่างนี้คือ ถ้าไม่ได้กรอกอีเมล ให้ใส่ “[email protected]” แทนโดยอัตโนมัติ

Trigger

SQL
DELIMITER //

CREATE TRIGGER before_user_insert_email
BEFORE INSERT ON users
FOR EACH ROW
BEGIN
  -- ถ้าไม่ได้กรอกอีเมล ให้ตั้งค่า default
  IF NEW.email IS NULL OR NEW.email = '' THEN
    SET NEW.email = '[email protected]';
  END IF;
END //

DELIMITER ;

ใช้ OLD และ NEW ใน AFTER UPDATE บันทึกการเปลี่ยนชื่อ

เป้าหมายของตัวอย่างนี้คือ เมื่อลูกค้าเปลี่ยนชื่อ ให้บันทึก log แสดงชื่อเก่าและชื่อใหม่

Trigger

SQL
DELIMITER //

CREATE TRIGGER after_customer_update
AFTER UPDATE ON customers
FOR EACH ROW
BEGIN
  -- ถ้าชื่อมีการเปลี่ยนแปลง
  IF OLD.name <> NEW.name THEN
    INSERT INTO customer_log(message, log_time)
    VALUES (
      CONCAT('เปลี่ยนชื่อจาก "', OLD.name, '" เป็น "', NEW.name, '"'),
      NOW()
    );
  END IF;
END //

DELIMITER ;

ทดสอบเปลี่ยนชื่อ

SQL
UPDATE customers
SET name = 'สมปอง'
WHERE id = 1;

เมื่อมีการเปลี่ยนแปลงข้อมูล ในตัวอย่างคือการเปลี่ยนชื่อ Trigger ที่เราสร้างไว้จะทำการบันทึกการเปลี่ยนแปลงตามที่กำหนด ดังตัวอย่าง

idmessagelog_time
1เปลี่ยนชื่อจาก “สมชาย” เป็น “สมปอง”2024-04-12 15:30:00

ใช้ OLD ใน BEFORE DELETE ย้ายข้อมูลก่อนลบ

เป้าหมายของตัวอย่างนี้คือ เมื่อลบลูกค้า ให้บันทึกชื่อไว้ในตาราง deleted_customers ก่อน

Trigger

SQL
DELIMITER //

CREATE TRIGGER before_customer_delete
BEFORE DELETE ON customers
FOR EACH ROW
BEGIN
  -- บันทึกชื่อผู้ที่ถูกลบลงในอีกตาราง
  INSERT INTO deleted_customers(name, deleted_at)
  VALUES (OLD.name, NOW());
END //

DELIMITER ;

บันทึกการอัปเดตข้อมูลลูกค้าทุกครั้ง

เป้าหมายของตัวอย่างนี้คือ ทุกครั้งที่มีการอัปเดตข้อมูลในตาราง customers ให้ระบบบันทึกค่าก่อนเปลี่ยนแปลง, ค่าหลังเปลี่ยนแปลง, และเวลาที่เปลี่ยน ลงในตาราง customer_audit_log

Trigger

SQL
DELIMITER //

CREATE TRIGGER after_customer_update_audit
AFTER UPDATE ON customers
FOR EACH ROW
BEGIN
  -- ตรวจสอบการเปลี่ยนแปลงชื่อ
  IF OLD.name <> NEW.name THEN
    INSERT INTO customer_audit_log(field_name, old_value, new_value, log_time)
    VALUES ('name', OLD.name, NEW.name, NOW());
  END IF;

  -- ตรวจสอบการเปลี่ยนแปลงอีเมล
  IF OLD.email <> NEW.email THEN
    INSERT INTO customer_audit_log(field_name, old_value, new_value, log_time)
    VALUES ('email', OLD.email, NEW.email, NOW());
  END IF;
END //

DELIMITER ;

ทดสอบอัปเดตข้อมูล

SQL
UPDATE customers
SET name = 'สมปอง',
    email = '[email protected]'
WHERE id = 1;

เมื่อมีการอัปเดตข้อมูล Trigger ที่เราสร้างไว้จะทำการบันทึกการเปลี่ยนแปลงตามที่เรากำหนด ดังตัวอย่าง

id field_name old_value new_value log_time
1 name สมชาย สมปอง 2024-04-12 16:15:00
2 email [email protected] [email protected] 2024-04-12 16:15:00

ข้อควรระวังในการใช้ OLD / NEW

  • ต้องใช้คู่กับ FOR EACH ROW เท่านั้น
  • ห้ามใช้ SET OLD.column = ... (เปลี่ยนค่าใน OLD ไม่ได้)
  • NEW ใช้ได้เฉพาะกับ INSERT/UPDATE
  • OLD ใช้ได้เฉพาะกับ UPDATE/DELETE
แชร์เรื่องนี้