Expo SQLite数据库无法存储数据问题排查求助
Expo React Native SQLite 插入数据失败排查与修复
问题背景
在Expo React Native项目中,SQLite数据库无法插入数据:数据可正常发送至PHP后端,但无法存入本地SQLite,且已确认数据库表创建正常。尝试过将代码放入useEffect钩子、使用openDatabaseAsync等不同数据库打开方式均无效,问题集中在使用userData状态的saveAccountInfo函数中。
排查到的核心问题
- 未定义变量错误:
saveAccountInfo的INSERT语句中使用了未定义的rsData变量,实际应使用组件状态userData。 - 缺失错误回调:
tx.executeSql未传入错误回调,无法捕获插入过程中的SQL语法、字段匹配等错误。 - 逻辑描述错误:插入成功回调中错误打印"Table created successfully",且嵌套查询未正确关联事务上下文。
- 冗余数据库实例:
continueOps函数重复创建数据库实例,可复用全局实例。
修复后的关键代码
useEffect(() => { const continueOps = (rsData) => { // 复用全局db实例,无需重新创建 db.transaction(tx => { tx.executeSql( `SELECT * FROM atlas_user_info WHERE user_ac_token = ?;`, [rsData.user_ac_token], (_, { rows }) => { console.log("查询结果:", rows._array); if(rows._array.length > 0){ navigation.navigate("Authenticated"); }else{ console.log("插入后未查询到数据,可能插入失败"); } }, (_, error) => { console.error("查询失败:", error); } ); }); }; const saveAccountInfo = () => { console.log("userData权限信息:", userData.pp_view); // 从userData中提取字段,添加默认值避免undefined const { user_id: userId, user_token: userToken, pp_view: ppView = 0, pp_manage: ppManage = 0, cb_view: cbView = 0, cb_manage: cbManage = 0, iv_view: ivView = 0, iv_manage: ivManage = 0, inv_view: invView = 0, inv_manage: invManage = 0 } = userData; db.transaction(tx => { tx.executeSql( `INSERT INTO atlas_user_info (user_db_id, user_names, user_ac_token, user_ac_status, pp_view, pp_manage, cb_view, cb_manage, iv_view, iv_manage, inv_view, inv_manage) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)`, [ userId, '', userToken, '', ppView, ppManage, cbView, cbManage, ivView, ivManage, invView, invManage ], (_, result) => { console.log("数据插入成功,插入ID:", result.insertId); // 同一事务内执行插入后查询 tx.executeSql( `SELECT * FROM atlas_user_info WHERE user_db_id = ?`, [userId], (_, { rows }) => console.log("插入后查询结果:", rows._array), (_, error) => console.error("插入后查询失败:", error) ); continueOps(userData); }, (_, error) => { console.error("插入失败:", error); // 捕获SQL错误 return true; // 终止事务,避免后续操作 } ); }); }; if(Object.entries(userData).length > 0){ saveAccountInfo(); } }, [userData]);
额外建议
- 字段类型验证:确保
atlas_user_info表的字段类型与插入值类型匹配,比如user_db_id若为整数,需保证userData.user_id不是字符串。 - 切换异步API:推荐使用Expo SQLite的异步API替代legacy同步API,更符合React Native异步逻辑:
// 替换全局db初始化 const [db, setDb] = useState(null); useEffect(() => { const initDb = async () => { const database = await SQLite.openDatabaseAsync("atlas.db"); setDb(database); }; initDb(); }, []);
内容的提问来源于stack exchange,提问作者El1Harolds
相关产品推荐
相关产品推荐

