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方法(参数化查询),自动处理类型转换和字符串转义:
修改插入方法
废弃原insertData2,改为直接接收数据Map的方法,确保获取正确的数据库实例:Future<int> insertExercise(Map<String, dynamic> exercise) async { Database db = await initialdatabase2(); // 直接调用初始化方法获取正确的DB实例 return await db.insert('exercises', exercise); }修改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()); } }额外检查项
- 确认
get2()方法返回的是initialdatabase2创建的exercises.db实例,若get2指向其他数据库,会导致插入数据不在目标表中。 - 确保
loadexercises()方法查询的是正确的exercises.db和exercises表。
- 确认
内容的提问来源于stack exchange,提问作者hamz
相关产品推荐
相关产品推荐

