You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Expo SQLite插入数据后无法返回新增行ID问题求助

问题解决:返回SQLite插入记录的ID

问题根源

  1. 异步操作未正确等待:你使用await db.transaction(...)时,transaction的回调内executeSql是异步回调逻辑,await仅等待transaction函数本身执行结束,不会等待内部executeSql的回调触发,导致函数提前返回时id还未被赋值。
  2. 调用异步函数未加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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.11 13:35:24