Android Kotlin中SQLite执行INSERT语句后行计数递增但数据未实际插入表中
Android Kotlin中SQLite执行INSERT语句后行计数递增但数据未实际插入表中
看起来你遇到的这个问题很典型,我帮你梳理下可能的原因和对应的解决办法:
1. 最可能的核心问题:表名不匹配
你创建表的语句明确指定了表名为 ReaderFlag:
CREATE TABLE IF NOT EXISTS ReaderFlag ( id INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, reader_customer_id INTEGER NOT NULL, reader_route_id INTEGER NOT NULL, start_end_flag TEXT NOT NULL );
但插入操作的目标表是 $Reader_Table 这个常量。请立刻确认 Reader_Table 的值是否严格等于 "ReaderFlag"。如果两者不一致,你其实是在往一个错误的表(甚至是SQLite自动创建的临时表)插入数据,而你查看的ReaderFlag表自然是空的。
2. 手动拼接SQL的风险与错误
你当前用字符串拼接的方式构造INSERT语句,这种做法很容易引发各种隐性问题:
- 特殊字符转义错误:比如
action.address里如果包含引号、反斜杠,会直接破坏SQL语法,导致插入失败(目前测试数据可能没这类字符,但隐患一直存在) - 字段值不符合业务逻辑:比如如果
action.start和action.stop同时为false,flagString会是空字符串——虽然空字符串满足NOT NULL约束,但这是否符合你的业务需求? - 代码可读性差,排查问题困难
3. 推荐的正确做法:使用ContentValues + insertOrThrow
你之前注释掉的ContentValues方案才是Android SQLite官方推荐的安全插入方式,它会自动处理字符串转义、字段类型匹配,还能通过insertOrThrow抛出明确的异常信息帮你快速定位问题。修改后的代码如下:
fun uploadFlagToCustomer( database: SQLiteDatabase, flags: List<StartStopPremisesFlag> ) { flags.forEach { action -> // 更简洁的flag字符串转换逻辑 val flagString = when { action.start -> "start" action.stop -> "stop" else -> "" // 这里建议根据业务需求处理,比如抛出异常或设置默认值 } val contentValues = ContentValues().apply { // 请确保ReaderTable的常量与数据表字段完全对应 put(ReaderTable.startEndFlag, flagString) put(ReaderTable.customerID, action.customer) put(ReaderTable.routeID, action.route) // 注意:如果要插入address字段,你需要先在ReaderFlag表中添加对应的字段(比如reader_customer_address),否则会抛出字段不存在的异常 // put(ReaderTable.customer_address, action.address.trim()) } try { val insertedRowId = database.insertOrThrow(Reader_Table, null, contentValues) println("成功插入,行ID:$insertedRowId") } catch (e: SQLiteException) { println("插入失败:${e.message}") e.printStackTrace() // 打印完整栈轨迹,方便定位问题 } } }
4. 额外验证步骤
为了确认数据是否真的被插入,你可以在插入后立刻查询目标表的行数:
// 在函数末尾或者循环内添加查询 val countCursor = database.rawQuery("SELECT COUNT(*) FROM $Reader_Table", null) if (countCursor.moveToFirst()) { val totalRows = countCursor.getInt(0) println("当前表${Reader_Table}的总行数:$totalRows") } countCursor.close()
5. 事务相关检查
如果你的代码在调用uploadFlagToCustomer之前开启了事务,但没有正确提交:
// 错误示例:开启事务但未提交 database.beginTransaction() uploadFlagToCustomer(database, flags) // 缺少 database.setTransactionSuccessful() 和 database.endTransaction()
这种情况下,所有插入操作都会被回滚,表数据不会被持久化。请确保事务的正确使用:
database.beginTransaction() try { uploadFlagToCustomer(database, flags) database.setTransactionSuccessful() // 标记事务成功 } catch (e: Exception) { println("事务执行失败:${e.message}") } finally { database.endTransaction() // 结束事务,成功则提交,失败则回滚 }
备注:内容来源于stack exchange,提问作者Jisa Joy
相关产品推荐
相关产品推荐

