直接答案
INSERT OR IGNORE INTO users (email, name)
VALUES ('a@example.com', 'Alice');
INSERT INTO users (email, name)
VALUES ('a@example.com', 'Alice')
ON CONFLICT(email) DO NOTHING;
这两种写法都依赖冲突目标:表里必须有 PRIMARY KEY、UNIQUE 约束或唯一索引,否则 SQLite 不知道什么叫“已存在”。
完整可运行示例
CREATE TABLE users (
id INTEGER PRIMARY KEY AUTOINCREMENT,
email TEXT NOT NULL UNIQUE,
name TEXT NOT NULL,
created_at TEXT NOT NULL DEFAULT CURRENT_TIMESTAMP
);
INSERT OR IGNORE INTO users (email, name)
VALUES ('a@example.com', 'Alice');
INSERT OR IGNORE INTO users (email, name)
VALUES ('a@example.com', 'Alice Again');
SELECT id, email, name FROM users;
第二次插入被忽略,原有行不会被更新。如果你需要“存在就更新”,使用 ON CONFLICT DO UPDATE。
几种写法怎么选
| 写法 | 行为 | 适合场景 |
|---|---|---|
INSERT OR IGNORE | 冲突时跳过整行 | 幂等导入、重复数据直接忽略 |
ON CONFLICT DO NOTHING | 指定冲突目标后跳过 | 语义更清晰的新写法 |
ON CONFLICT DO UPDATE | 冲突时更新已有行 | upsert,例如同步配置 |
WHERE NOT EXISTS | 通过查询判断是否插入 | 复杂条件,但并发下仍建议唯一约束兜底 |
存在就更新:SQLite upsert
INSERT INTO users (email, name)
VALUES ('a@example.com', 'Alice Updated')
ON CONFLICT(email) DO UPDATE SET
name = excluded.name;
excluded 表示本次试图插入的新值。它类似 MySQL 里的新行别名,但 SQLite 语法不是 ON DUPLICATE KEY UPDATE。
和 MySQL 的区别
MySQL 常见写法是 INSERT IGNORE 或 INSERT ... ON DUPLICATE KEY UPDATE;SQLite 使用 INSERT OR IGNORE 和 ON CONFLICT。两者都依赖唯一键识别冲突,但语法和细节不同。更多 MySQL 插入模式可回到 SQL 数据操作章节。