Computer >> บทช่วยสอนคอมพิวเตอร์ >  >> การเขียนโปรแกรม >> MySQL

ใช้ INSERT ... ON DUPLICATE KEY UPDATE ใน MySQL (Upsert)

คำสั่ง INSERT ... ON DUPLICATE KEY UPDATE (Upsert)

ทำงานแบบ: **ลอง Insert ก่อน → หากเจอ Duplicate Key (PK/Unique) ให้ Update แทน** เหมาะสำหรับ Sync Data, Counter, Cache

Syntax

INSERT INTO table (col1, col2, ...) 
VALUES (val1, val2, ...)
ON DUPLICATE KEY UPDATE col2 = new_val, col3 = new_val, ...;

ตัวอย่าง: Unique Key บน StudentName

สร้างตารางมี Unique Key บน StudentName:

mysql> CREATE TABLE DemoTable733 (
    StudentId INT NOT NULL AUTO_INCREMENT PRIMARY KEY,
    StudentName VARCHAR(100),
    StudentMarks INT,
    UNIQUE KEY Un_Name (StudentName)
);
Query OK, 0 rows affected (0.60 sec)

Insert ครั้งแรก (John, Adam, Carol) - ทั้งหมด Insert ใหม่:

mysql> INSERT INTO DemoTable733 (StudentName, StudentMarks) VALUES 
    ('John', 45) ON DUPLICATE KEY UPDATE StudentMarks = 86;
Query OK, 1 row affected (0.19 sec)

mysql> INSERT INTO DemoTable733 (StudentName, StudentMarks) VALUES 
    ('Adam', 65) ON DUPLICATE KEY UPDATE StudentMarks = 86;
Query OK, 1 row affected (0.15 sec)

mysql> INSERT INTO DemoTable733 (StudentName, StudentMarks) VALUES 
    ('Carol', 75) ON DUPLICATE KEY UPDATE StudentMarks = 86;
Query OK, 1 row affected (0.08 sec)

Insert ซ้ำ (John อีกครั้ง) → **Update** StudentMarks = 86:

mysql> INSERT INTO DemoTable733 (StudentName, StudentMarks) VALUES 
    ('John', 45) ON DUPLICATE KEY UPDATE StudentMarks = 86;
Query OK, 2 rows affected (0.12 sec)

ผลลัพธ์ - John มี Marks = 86 (Updated), Adam/Carry คงค่า Insert เดิม:

mysql> SELECT * FROM DemoTable733;
+-----------+-------------+--------------+
| StudentId | StudentName | StudentMarks |
+-----------+-------------+--------------+
| 1         | John        | 86           |
| 2         | Adam        | 65           |
| 3         | Carol       | 75           |
+-----------+-------------+--------------+
3 rows in set (0.00 sec)

จุดสำคัญ

  • ต้องมี **Primary Key** หรือ **Unique Index** ถึงจะ Trigger Duplicate
  • VALUES(col) ในส่วน UPDATE = ค่าที่พยายาม Insert (ไม่ใช่ค่าเก่า):
    ON DUPLICATE KEY UPDATE StudentMarks = VALUES(StudentMarks) + 10;
  • คืนค่า Rows Affected: 1 = Insert, 2 = Update, 0 = No Change (หากค่าเหมือนเดิมและ MySQL Optimize)
  • หลายแถวพร้อมกัน:
    INSERT INTO t (a,b) VALUES (1,2),(2,3),(3,4) ON DUPLICATE KEY UPDATE b=VALUES(b);

INSERT IGNORE vs ON DUPLICATE KEY UPDATE

คำสั่งพฤติกรรมเมื่อ Duplicate
INSERT IGNOREข้ามไป (Silent), ไม่ Error, ไม่ Update
ON DUPLICATE KEY UPDATEUpdate คอลัมน์ที่ระบุ
REPLACE INTODelete แถวเก่า + Insert ใหม่ (Auto Increment เปลี่ยน)

MySQL 8.0.19+: INSERT ... ON DUPLICATE KEY UPDATE ... WHERE

INSERT ... ON DUPLICATE KEY UPDATE col = new_val WHERE some_condition;