MySQL ไม่รองรับ การใช้ Function (เช่น NOW(), UUID(), RAND()) เป็น DEFAULT VALUE โดยตรง (ยกเว้น CURRENT_TIMESTAMP สำหรับ TIMESTAMP/DATETIME)
วิธีแก้: ใช้ BEFORE INSERT TRIGGER
1. สร้างตาราง
CREATE TABLE TbLFunctionTrigger (
id CHAR(36), -- สำหรับ UUID
username VARCHAR(100)
);
2. สร้าง Trigger ก่อน Insert
DELIMITER //
CREATE TRIGGER insertBef
BEFORE INSERT ON TbLFunctionTrigger
FOR EACH ROW
BEGIN
IF NEW.id IS NULL OR NEW.id = '' THEN
SET NEW.id = UUID();
END IF;
END //
DELIMITER ;
3. ทดสอบ Insert
INSERT INTO TbLFunctionTrigger (username) VALUES ('John');
INSERT INTO TbLFunctionTrigger (username) VALUES ('Jane');
SELECT * FROM TbLFunctionTrigger;
+--------------------------------------+----------+
| id | username |
+--------------------------------------+----------+
| 550e8400-e29b-41d4-a716-446655440000 | John |
| 550e8400-e29b-41d4-a716-446655440001 | Jane |
+--------------------------------------+----------+
ตัวอย่าง Default Values อื่นๆ ด้วย Trigger
Default Timestamp (หากไม่ใช่ TIMESTAMP Column)
CREATE TRIGGER set_created_at
BEFORE INSERT ON my_table
FOR EACH ROW
SET NEW.created_at = IFNULL(NEW.created_at, NOW());
Default Random Number
CREATE TRIGGER set_random_token
BEFORE INSERT ON tokens
FOR EACH ROW
SET NEW.token = FLOOR(RAND() * 1000000);
Default จาก Table อื่น
CREATE TRIGGER set_default_category
BEFORE INSERT ON products
FOR EACH ROW
BEGIN
IF NEW.category_id IS NULL THEN
SELECT id INTO NEW.category_id FROM categories WHERE is_default = 1 LIMIT 1;
END IF;
END;
ข้อจำกัดของ Trigger Default
- เพิ่ม Overhead เล็กน้อยตอน INSERT
- ไม่ทำงานกับ
LOAD DATA INFILE(บาง Version) - Debug ยากกว่า Default Value ธรรมดา
- ต้องระวัง Recursive Trigger
MySQL 8.0.13+ รองรับ Functional Default
-- MySQL 8.0.13+ รองรับได้บาง Function
CREATE TABLE t (
id INT PRIMARY KEY,
created_at DATETIME DEFAULT (NOW()), -- Works!
uuid_val CHAR(36) DEFAULT (UUID()) -- Works!
);
⚠️ แต่ยังมีข้อจำกัด: ไม่รองรับ Subquery, Stored Functions, Variables