INSERT INTO person(id, name, age, info)
SELECT id, name, age, info FROM person_old;
| 方案 | MySQL 語法 | 行為 | SQL Server 對應 |
|---|---|---|---|
| 忽略衝突 | INSERT IGNORE INTO ... | 衝突行靜默跳過,不報錯,不回滾其他行 | 建表指定 WITH (IGNORE_DUP_KEY = ON) (僅適用唯一索引,非主鍵) |
| 替換現有 | REPLACE INTO ... | 衝突時**先刪除舊行,再插入新行** (觸發 DELETE+INSERT 觸發器,自增 ID 會變) | MERGE / UPSERT 模式 |
| 更新現有 | INSERT ... ON DUPLICATE KEY UPDATE col=VALUES(col) | 衝突時**更新指定列**,保留主鍵 ID,性能最佳 | MERGE / UPSERT |
實戰演示 INSERT IGNORE:
TRUNCATE TABLE person;
INSERT INTO person_old VALUES (11,'Harry',20,'student'),(12,'Beckham',31,'police');
INSERT INTO person(id,name,age,info) SELECT id,name,age,info FROM person_old; -- 成功
INSERT INTO person_old VALUES (13,'Kay',26,'student'); -- 新增一行
INSERT IGNORE INTO person(id,name,age,info) SELECT id,name,age,info FROM person_old; -- 僅插入 Kay,前兩行忽略
SET IDENTITY_INSERT tbl ON 才能顯式插入自增值,否則報錯。插入後需 OFF。INSERT INTO person(id,name,age,info) VALUES (16,'Tom',88,'student') (無衝突即可)INSERT INTO person(id,name,age,info) VALUES (NULL,'Amy',12,'bb') → 自動生成INSERT INTO person(name,age,info) VALUES ('Amy',12,'bb') → 自動生成INSERT INTO t(a) VALUES (NULL), (NULL); 成功Cannot insert duplicate key row ... value is 語法基本一致,MySQL 支持多表更新:
UPDATE person p
JOIN person_old o ON p.id = o.id
SET p.info = 'police'
WHERE p.id BETWEEN 14 AND 17;
| 命令 | 行為 | 速度 | 自增計數器 | 觸發器 |
|---|---|---|---|---|
DELETE FROM person WHERE id BETWEEN 14 AND 17 | 逐行刪除,記錄 Binlog (ROW 格式每行一條) | 慢 | 保留 | 觸發 FOR EACH ROW |
TRUNCATE TABLE person | 直接釋放數據頁,重建表結構,不記錄行級 Binlog | 極快 | **重置為 1** | **不觸發** |
驗證自增重置:
TRUNCATE TABLE person;
INSERT INTO person(name,age,info) VALUES ('Amy',12,'bb');
SHOW TABLE STATUS LIKE 'person';
-- Auto_increment: 2 (說明從 1 開始)
IGNORE/REPLACE/ON DUPLICATE KEY UPDATE 三利器,靈活強大;SQL Server 依賴表選項 IGNORE_DUP_KEY 或 MERGEIDENTITY_INSERT