SQLite3中批量Upsert数据的更优实现方式咨询
SQLite3 批量Upsert实现方案
针对你需要批量执行Upsert的场景,SQLite 3.24.0及以上版本支持两种简洁的批量实现方式,完全可以替代重复的单条语句:
1. 直接批量VALUES写法
这是最直观的批量Upsert方式,把所有待插入的行合并到一个VALUES子句中,仅需执行一次语句:
INSERT INTO `station` (`id`, `is_mirrored`) VALUES ('station1', TRUE), ('station2', TRUE), ('station3', TRUE), ('station4', TRUE) ON CONFLICT(`id`) DO UPDATE SET `is_mirrored` = EXCLUDED.`is_mirrored`;
这里用EXCLUDED.is_mirrored``替代硬编码的TRUE,能保证更新的值和插入时的一致,避免后续修改值时需要改两处。
2. 基于逗号分隔ID列表的动态批量Upsert
如果你的输入是逗号分隔的ID字符串(比如'station1,station2,station3,station4'),可以用SQLite的字符串函数结合CTE(公共表表达式)拆分列表后执行Upsert:
WITH split_ids(id) AS ( SELECT trim(value) FROM string_split('station1,station2,station3,station4', ',') ) INSERT INTO `station` (`id`, `is_mirrored`) SELECT id, TRUE FROM split_ids ON CONFLICT(`id`) DO UPDATE SET `is_mirrored` = TRUE;
低版本兼容方案(SQLite < 3.40.0)
如果你的SQLite版本低于3.40.0(无string_split函数),可以用递归CTE实现字符串拆分:
WITH RECURSIVE split_ids(id, rest) AS ( SELECT '', 'station1,station2,station3,station4,' UNION ALL SELECT substr(rest, 1, instr(rest, ',') - 1), substr(rest, instr(rest, ',') + 1) FROM split_ids WHERE rest != '' ) INSERT INTO `station` (`id`, `is_mirrored`) SELECT id, TRUE FROM split_ids WHERE id != '' ON CONFLICT(`id`) DO UPDATE SET `is_mirrored` = TRUE;
关键注意点
- 必须确保
station表的id字段已设置唯一约束(主键或唯一索引),否则ON CONFLICT子句不会生效。
内容的提问来源于stack exchange,提问作者Andrew Vaughan
相关产品推荐
相关产品推荐

