如何在React Native SQLite中使用upsert实现存在更新不存在插入
问题原因排查及修复方案
你的代码存在以下4个核心问题:
- SQL参数数量不匹配:你写了两条SQL语句,一共5个占位符(INSERT语句2个,UPDATE语句3个),但你只传入了2个参数,SQL执行直接失败,你没有配置错误回调所以看不到报错。
- JS语法错误:
console.log('success')后多了一个多余的右括号,代码直接编译/运行报错。
- JS语法错误:
- 缺少唯一约束:
INSERT OR IGNORE依赖唯一约束判断重复,你需要先给app_name字段添加UNIQUE约束,否则插入永远不会触发忽略逻辑,UPDATE语句永远不会执行。
- 缺少唯一约束:
- 多语句执行兼容问题:部分React Native SQLite插件默认不支持单条
executeSql执行多条SQL语句,且多语句执行后rowsAffected只会返回最后一条语句的影响行数,判断逻辑不可靠。
- 多语句执行兼容问题:部分React Native SQLite插件默认不支持单条
最优修复方案(推荐使用SQLite原生UPSERT语法)
SQLite 3.24.0及以上版本(目前React Native集成的SQLite版本基本都满足要求)支持原生UPSERT语法,单条语句即可实现存在更新、不存在插入的逻辑,不需要拆分两条语句:
INSERT INTO client_registration (app_name, key) VALUES (?, ?) ON CONFLICT(app_name) DO UPDATE SET key = excluded.key
修正后完整代码:
// 首先建表时必须给app_name加UNIQUE约束,只需要执行一次 db.transaction(tx => { tx.executeSql(` CREATE TABLE IF NOT EXISTS client_registration ( app_name TEXT UNIQUE NOT NULL, key TEXT NOT NULL ) `) }) // 执行upsert逻辑 db.transaction(function (tx) { tx.executeSql( 'INSERT INTO client_registration (app_name, key) VALUES (?, ?) ON CONFLICT(app_name) DO UPDATE SET key = excluded.key', ['coin', '123'], (tx, results) => { if (results.rowsAffected > 0) { console.log('success') } else { console.log('Registration Failed') } }, // 新增错误回调,方便排查问题 (tx, error) => { console.log('执行错误:', error) return false // 中断事务 } ); });
如果你要保留原有双语句写法,按以下修改:
- 补全5个参数:
['coin', '123', 'coin', '123', 'coin'] - 删掉多余的右括号
- 加上错误回调
内容的提问来源于stack exchange,提问作者user
相关产品推荐
相关产品推荐

