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

SQLite查询单条记录触发CursorIndexOutOfBoundsException问题求助

解决SQLite CursorIndexOutOfBoundsException的正确姿势

这个问题我太熟悉了!你遇到的java.lang.CursorIndexOutOfBoundsException: Index -1 requested本质原因有两个:

  1. SQLite Cursor的默认起始位置是索引-1,你直接调用cursor.getLong(0)时,根本还没指向任何一条有效记录;
  2. 你没有做数据存在性判断,如果表中ID=1的记录不存在(比如表是空的),同样会触发这个错误。

直接返回数组取get(0)确实是偷懒的做法,下面给你一套规范且健壮的实现方案:

核心修复点

  • 必须先调用cursor.moveToFirst()将Cursor移动到第一条记录,该方法会返回boolean值,true表示存在有效记录;
  • 用参数化查询代替直接拼接SQL(哪怕是固定ID,这也是防止SQL注入的最佳实践);
  • 用列名获取索引代替硬编码数字索引,避免表结构变化导致的错误;
  • 确保Cursor资源被正确关闭,避免内存泄漏;
  • 处理没有找到记录的边界情况。

完整代码实现

public User_Token getUser_TokenDB() {
    User_Token auxUserToken = null;
    // 使用参数化查询,?是占位符
    String sql = "SELECT * FROM " + TABLE_NAME_USER_TOKEN + " WHERE ID = ?";
    Cursor cursor = this.database.rawQuery(sql, new String[]{"1"});

    try {
        // 先移动到第一条记录,判断是否存在有效数据
        if (cursor != null && cursor.moveToFirst()) {
            // 用getColumnIndexOrThrow获取列索引,比硬编码数字更健壮
            auxUserToken = new User_Token(
                cursor.getLong(cursor.getColumnIndexOrThrow("ID")),
                cursor.getString(cursor.getColumnIndexOrThrow("token_column1")), // 替换成你的实际列名
                cursor.getString(cursor.getColumnIndexOrThrow("token_column2")),
                cursor.getString(cursor.getColumnIndexOrThrow("token_column3"))
            );
        }
    } catch (IllegalArgumentException e) {
        // 处理列名不存在的异常,方便排查表结构问题
        e.printStackTrace();
    } finally {
        // 确保Cursor被关闭,放在finally块里不管是否异常都会执行
        if (cursor != null) {
            cursor.close();
        }
    }

    return auxUserToken;
}

使用说明

调用这个方法时,记得判断返回值是否为null,处理没有找到记录的情况:

User_Token userToken = getUser_TokenDB();
if (userToken != null) {
    // 正常处理数据
} else {
    // 没有找到ID=1的记录,做提示或其他逻辑
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.15 08:46:54