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

使用Kotlin调用SQLite数据库查询函数时出现错误求助

解决Android Kotlin中SQLite查询readChore函数的错误

从你给出的代码片段来看,几个明显的问题会导致查询出错,我来逐一拆解并给出修复方案:

1. 查询列缺失,构造Chore时引用不存在的列

你在db.query方法里指定的查询列是KEY_ID, KEY_CHORE_ASSIGNED_TO, KEY_CHORE_ASSIGNED_BY, KEY_CHORE_ASSINED_TIME,但后面构造Chore对象时却尝试获取KEY_CHORE_NAME的值——这个列根本没被包含在查询结果里!cursor.getColumnIndex(KEY_CHORE_NAME)会返回-1,调用getString(-1)直接触发崩溃。

2. 拼写错误导致列名不匹配

注意到你写了KEY_CHORE_ASSINED_TIME,这里少了一个字母G,应该是KEY_CHORE_ASSIGNED_TIME。如果你的数据库表结构里列名是正确的ASSIGNED,这个拼写错误会导致查询时找不到对应列,同样引发异常。

3. 未处理Cursor为空/无数据的情况

调用cursor.moveToFirst()之后,没有判断操作是否成功(比如当数据库里没有对应ID的数据时,moveToFirst()会返回false),直接去取数据会导致空指针或索引越界错误。

4. 未关闭Cursor和数据库连接

查询完成后没有关闭Cursor和SQLiteDatabase,会造成资源泄漏,长期运行可能导致性能问题或异常。


修正后的完整函数示例

fun readChore(id: Int): Chore? {
    var db: SQLiteDatabase? = null
    var cursor: Cursor? = null
    return try {
        db = writableDatabase
        // 修正拼写错误,同时加入KEY_CHORE_NAME到查询列中
        val columns = arrayOf(KEY_ID, KEY_CHORE_NAME, KEY_CHORE_ASSIGNED_TO, 
                              KEY_CHORE_ASSIGNED_BY, KEY_CHORE_ASSIGNED_TIME)
        cursor = db.query(
            TABLE_NAME,
            columns,
            "$KEY_ID=?",
            arrayOf(id.toString()),
            null,
            null,
            null
        )
        Log.d("position", cursor.position.toString())
        
        // 先判断Cursor是否有数据
        if (cursor.moveToFirst()) {
            Chore(
                cursor.getString(cursor.getColumnIndexOrThrow(KEY_CHORE_NAME)),
                cursor.getString(cursor.getColumnIndexOrThrow(KEY_CHORE_ASSIGNED_TO)),
                cursor.getString(cursor.getColumnIndexOrThrow(KEY_CHORE_ASSIGNED_BY)),
                // 这里根据你的Chore构造函数,补充剩余参数,比如时间字段
                cursor.getString(cursor.getColumnIndexOrThrow(KEY_CHORE_ASSIGNED_TIME))
                // 如果有其他字段,继续添加
            )
        } else {
            // 没有找到对应ID的数据,返回null
            null
        }
    } catch (e: Exception) {
        // 捕获异常并打印日志,方便排查
        Log.e("ReadChoreError", "Failed to read chore: ${e.message}", e)
        null
    } finally {
        // 确保关闭Cursor和数据库
        cursor?.close()
        db?.close()
    }
}

额外提醒

  • 建议使用getColumnIndexOrThrow()替代getColumnIndex(),这样如果列名错误会直接抛出异常,方便你快速定位问题,而不是默默返回-1导致后续崩溃。
  • 如果你的Chore类构造函数需要KEY_ID参数,记得在查询列里加入它,并在构造时传入对应的值。
  • 数据库操作建议放在子线程中执行,避免阻塞主线程引发ANR问题。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.20 12:29:39