Expo SQLite插入数据后无法返回新增行ID问题求助
问题解决:返回SQLite插入记录的ID
问题根源
- 异步操作未正确等待:你使用
await db.transaction(...)时,transaction的回调内executeSql是异步回调逻辑,await仅等待transaction函数本身执行结束,不会等待内部executeSql的回调触发,导致函数提前返回时id还未被赋值。 - 调用异步函数未加
await:insertWorkout是异步函数,直接调用database.insertWorkout(workoutName)会得到Promise对象,而非实际的ID值。
解决方案
1. 重构insertWorkout函数,用Promise封装事务操作
将整个插入逻辑包装成Promise,确保在executeSql回调触发后再返回ID:
const insertWorkout = async (name) => { // 注意:getDate()仅返回当月日期,若需存储完整时间建议用toISOString() const date = new Date().toISOString(); return new Promise((resolve, reject) => { db.transaction(tx => { tx.executeSql( 'INSERT INTO workouts (name, created_at) values (?, ?)', [name, date], (_, resultSet) => { console.log('插入成功,ID:', resultSet.insertId); resolve(resultSet.insertId); }, (_, err) => { console.error('插入失败:', err); reject(err); // 返回true表示已处理错误,避免事务自动回滚的默认行为(可选) return true; } ); }); }); };
2. 调用函数时添加await
在handleAddWorkoutModal中,调用insertWorkout必须用await才能获取实际ID:
const handleAddWorkoutModal = async (workoutName, setShowAddWorkoutModal, router) => { try { // 添加await等待异步操作完成 const id = await database.insertWorkout(workoutName); console.log('获取到的ID:', id); setShowAddWorkoutModal(false); router.push({ pathname: '/pages/workouts/createWorkout/CreateWorkout', params: { workoutName: workoutName, workoutId: id } }); } catch (e) { console.warn('添加训练记录失败:', e); } }; export default handleAddWorkoutModal;
补充说明
- 针对
RETURNING语句的问题:上述方案通过回调获取insertId可以绕过Expo SQLite对该语句的支持限制,这也是Expo SQLite获取插入ID的标准方式。 - 日期字段优化:如果
created_at需要存储完整时间戳,建议使用new Date().toISOString(),而非仅返回当月日数的getDate()。
内容的提问来源于stack exchange,提问作者Spartis
相关产品推荐
相关产品推荐

