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

sqflite的rawInsert方法未插入全部字段问题排查求助

问题描述

在gym_tracker应用中向exercises表插入数据时,出现部分字段插入失败的情况:workoutname和weight字段值为null,但Cubit调用方法中打印所有参数均有有效值。使用sqflite操作数据库,相关代码如下:

表创建方法

Future<Database> initialdatabase2() async {
    String databasepath = await getDatabasesPath();
    var path = join(databasepath, "exercises.db");
    Database mydb = await openDatabase(path,
        onCreate: _oncreate2, version: 1, onUpgrade: _onupgrade);
    return mydb;
  }

//exercise db
  _oncreate2(Database db2, int version) async {
    await db2.execute('''
CREATE TABLE "exercises" 
(id INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT , workoutname Text , exercisename Text , sets INTEGER , reps INTEGER , weight REAL
) 
    ''');

插入方法

insertData2(String sql) async {
    Database? db = await get2();
    int response = await db!.rawInsert(sql);
    return response;
  }

Cubit调用代码

void addexercise(
      {required String name,
      required String workoutname,
      required int reps,
      required int sets,
      required double weight}) async {
    print(name);
    print(workoutname);
    print(reps);
    print(sets);
    print(weight);
    emit(ExercisesListLoadingState());
    await casheHelper
        .insertData2(
            "INSERT INTO 'exercises' (workoutname ,exercisename , sets ,reps ,weight) VALUES ('$workoutname','$name',$sets ,$reps ,$weight )")
        .then((value) {
      exercisesname = [];
      loadexercises();
      print("exercise added");
      emit(ExercisesListAddSuccessState());
    });
  }
问题排查与解决

核心问题:手动拼接SQL字符串的隐性错误

手动拼接SQL语句容易引发字符串转义、类型解析等隐性问题,比如workoutname包含特殊字符(如单引号、空格)时会破坏SQL语法,或weight的浮点格式因地区设置(如逗号作为小数点)导致解析失败,最终插入null。此外,这种写法还存在SQL注入风险。

解决方案:使用sqflite参数化插入

替换手动拼接SQL的方式,改用sqflite内置的insert方法(参数化查询),自动处理类型转换和字符串转义:

  1. 修改插入方法
    废弃原insertData2,改为直接接收数据Map的方法,确保获取正确的数据库实例:

    Future<int> insertExercise(Map<String, dynamic> exercise) async {
      Database db = await initialdatabase2(); // 直接调用初始化方法获取正确的DB实例
      return await db.insert('exercises', exercise);
    }
    
  2. 修改Cubit中的调用逻辑
    用参数Map替代SQL字符串拼接,并添加错误捕获:

    void addexercise({
      required String name,
      required String workoutname,
      required int reps,
      required int sets,
      required double weight
    }) async {
      print(name);
      print(workoutname);
      print(reps);
      print(sets);
      print(weight);
      emit(ExercisesListLoadingState());
      try {
        await casheHelper.insertExercise({
          'workoutname': workoutname,
          'exercisename': name,
          'sets': sets,
          'reps': reps,
          'weight': weight
        });
        exercisesname = [];
        await loadexercises(); // 等待数据加载完成再更新状态
        print("exercise added");
        emit(ExercisesListAddSuccessState());
      } catch (e) {
        print('插入失败:$e');
        // 建议添加错误状态,让UI处理异常
        emit(ExercisesListAddErrorState());
      }
    }
    
  3. 额外检查项

    • 确认get2()方法返回的是initialdatabase2创建的exercises.db实例,若get2指向其他数据库,会导致插入数据不在目标表中。
    • 确保loadexercises()方法查询的是正确的exercises.db和exercises表。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.27 20:17:01