業務常見需求:插入前檢查記錄是否存在,僅在不存在時插入。MySQL 提供多種實現方案,核心思路是利用 NOT EXISTS 子查詢。
INSERT INTO clients (client_id, client_name, client_type)
SELECT supplier_id, supplier_name, 'advertising'
FROM suppliers
WHERE NOT EXISTS (
SELECT 1 FROM clients
WHERE clients.client_id = suppliers.supplier_id
);
子查詢檢查目標表中是否已存在相同 client_id,不存在則插入。
INSERT INTO clients (client_id, client_name, client_type)
SELECT 10345, 'IBM', 'advertising'
FROM dual
WHERE NOT EXISTS (
SELECT 1 FROM clients
WHERE clients.client_id = 10345
);
dual 是虛擬表,允許 SELECT 直接跟常量值,無需關聯實體表。
| 方案 | 優點 | 缺點 |
|---|---|---|
| NOT EXISTS | 標準 SQL、可讀性好、支持複雜條件 | 需掃描目標表索引 |
| INSERT IGNORE | 語法簡單、性能略優 | 會吞噬其他錯誤(如外鍵衝突) |
| ON DUPLICATE KEY UPDATE | 可更新已有行 | 需唯一索引、意圖不純粹 |
| REPLACE INTO | 語法簡潔 | 實際是 DELETE+INSERT,觸發器行為異常 |
client_id 為主鍵)SELECT ... FOR UPDATE 或使用事務