SQLite如何避免重复插入 仅新增不存在的记录
SQLite重复插入数据修复方案
重复插入的核心原因:
- 表结构未给业务唯一标识
genre_id添加唯一约束,数据库无法自动识别重复记录 - 使用普通
INSERT语法无存在性校验逻辑,只要执行就会写入新行 - 原有插入代码存在字段映射错误:后端返回字段为
genre_id、genre_name,代码中错误引用了genre.id、genre.name
步骤1:给genre_id添加唯一约束
从表结构层面限制同一个genre_id只能存储一条记录,从根源避免重复脏数据:
- 若表尚未创建,直接修改建表语句:
CREATE TABLE IF NOT EXISTS " + this.GENRES_TABLE_NAME + " ( _id integer primary key autoincrement, genre_id integer UNIQUE, genre_name text );
- 若表已存在存量数据,执行新增唯一索引的语句即可:
CREATE UNIQUE INDEX IF NOT EXISTS idx_unique_genre_id ON " + this.GENRES_TABLE_NAME + "(genre_id);
步骤2:替换插入语法为INSERT OR IGNORE
SQLite原生支持INSERT OR IGNORE语法:插入数据时如果触发唯一约束冲突(即对应genre_id已存在),会自动跳过该条记录,仅写入不存在的新数据。
修正字段映射+转义逻辑后的完整插入代码:
let insertSQL = `INSERT OR IGNORE INTO ${this.GENRES_TABLE_NAME} (genre_id, genre_name) VALUES `; genres.forEach((genre, index) => { // 对齐后端返回字段名,同时转义名称中的双引号避免SQL语法错误 const safeName = genre.genre_name.replace(/"/g, '""'); insertSQL += `(${genre.genre_id},"${safeName}")`; if (index < genres.length - 1) { insertSQL += ","; } }); insertSQL += ";"; db.executeSql(insertSQL);
执行上述代码后,已存在的genre_id=43、genre_id=44记录会被自动跳过,仅插入genre_id=111的新记录,完全匹配需求。
可选方案(不修改表结构场景)
如果暂时不调整表结构,可以用NOT EXISTS在插入前做存在性校验,但是批量写入性能低于上述方案,单条插入语法示例:
INSERT INTO genres (genre_id, genre_name) SELECT 111, 'new collection' WHERE NOT EXISTS (SELECT 1 FROM genres WHERE genre_id = 111);
批量写入时按该语法拼接所有待插入记录即可,不推荐长期使用该方案,无法从底层避免其他写入逻辑产生重复数据。
内容的提问来源于stack exchange,提问作者Joshi G
相关产品推荐
相关产品推荐

