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

使用expo-sqlite初始化数据库时遇非标准C++异常等错误求助

解决expo-sqlite在Expo Go iOS真机上的初始化错误

问题根源

你的代码存在两个核心问题:

  • 模块顶层直接使用await:ES模块顶层await虽有支持,但在Expo/React Native的模块加载环境中,可能打乱初始化时序,引发底层原生错误。
  • 数据库实例与初始化逻辑分离:nutriDB在模块加载阶段就尝试创建,此时App原生环境可能尚未完成初始化,导致后续execAsync调用失败。

修复方案

修改代码,将数据库实例创建与初始化逻辑合并,确保所有异步操作在App启动后有序执行:

import * as SQLite from 'expo-sqlite';

// 声明数据库实例变量
let nutriDB;

const initializeDatabase = async () => {
  try {
    // 先完成数据库实例创建
    nutriDB = await SQLite.openDatabaseAsync('nutritionDB.db');
    
    // 拆分执行PRAGMA与建表语句,避免语法或执行顺序冲突
    await nutriDB.execAsync('PRAGMA journal_mode = WAL;');
    await nutriDB.execAsync(`
      CREATE TABLE IF NOT EXISTS NutritionInput (
        NutritionInputID INTEGER PRIMARY KEY AUTOINCREMENT,
        Date TEXT,
        FoodEntries TEXT,
        MealType TEXT CHECK (MealType IN ('Breakfast', 'Lunch', 'Dinner', 'Snack')),
        TransFat REAL CHECK(TransFat >= 0),
        SatFat REAL CHECK (SatFat >= 0),
        TotalCalories REAL CHECK (TotalCalories >= 0)
      );
    `);

    console.log('Nutrition table initialized successfully!');
  } catch (error) {
    console.error('Error initializing database: ', error);
    throw error; // 抛出错误便于调用者捕获处理
  }
};

// 导出安全的数据库实例访问方法与初始化函数
export default { 
  getDB: () => nutriDB,
  initializeDatabase 
};

正确调用方式

在App入口组件中触发数据库初始化,确保App启动后完成数据库准备:

import { useEffect } from 'react';
import { View, Text } from 'react-native';
import db from './path/to/your/database/file';

export default function App() {
  useEffect(() => {
    const setupDB = async () => {
      try {
        await db.initializeDatabase();
        // 初始化完成后再执行数据库操作
        const dbInstance = db.getDB();
        // 示例:验证表是否创建成功
        const result = await dbInstance.getFirstAsync("SELECT name FROM sqlite_master WHERE type='table' AND name='NutritionInput';");
        console.log('Table exists:', !!result);
      } catch (err) {
        console.error('App startup DB error:', err);
      }
    };

    setupDB();
  }, []);

  return (
    <View>
      <Text>Testing Expo SQLite</Text>
    </View>
  );
}

额外注意事项

  • iOS权限配置:若遇到存储权限问题,可在app.json中添加NSDocumentsFolderUsageDescription权限说明,确保Expo Go能正常访问设备存储。
  • SQL语法校验:检查CHECK约束的格式,确保数值类型的约束条件无语法错误。
  • 详细错误排查:若仍有错误,在catch块中打印error.message和error.stack,获取更具体的原生错误信息。

内容的提问来源于stack exchange,提问作者shojojo27

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.21 00:07:15