← 返回 SQL 教程

SQLite insert if not exists:避免重复插入

SQLite 里不要直接照搬 MySQL 的 ON DUPLICATE KEY UPDATE。常用写法是唯一约束配合 INSERT OR IGNOREON CONFLICT DO NOTHING

直接答案

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 KEYUNIQUE 约束或唯一索引,否则 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 IGNOREINSERT ... ON DUPLICATE KEY UPDATE;SQLite 使用 INSERT OR IGNOREON CONFLICT。两者都依赖唯一键识别冲突,但语法和细节不同。更多 MySQL 插入模式可回到 SQL 数据操作章节