SQLite获取最大数值行报错:CursorWindow读取列-1失败
解决CursorWindow读取列-1的错误:获取指定exercise最大reps行
这个错误CursorWindow: Failed to read row 0, column -1本质是你在访问Cursor里不存在的列,结合你说的查询场景,大概率是这两个问题:要么SQL查询只返回了单个聚合值(比如MAX(reps))而非整行数据,要么你在获取列索引时用错了列名。下面一步步帮你解决:
第一步:检查并修正你的SQL查询语句
你需要获取的是某一exercise中reps最大的整行数据,如果你的SQL写成了类似:
SELECT MAX(reps) FROM your_table WHERE excersise = '目标运动'
那返回的Cursor只有1行1列(就是最大的reps数值),没有_ID、excersise、timestamp这些列,这时候你去调用cursor.getColumnIndex("_ID")就会返回-1,自然触发错误。
正确的SQL应该返回整行数据,推荐用ORDER BY + LIMIT的方式(比子查询更高效):
SELECT * FROM your_table WHERE excersise = ? ORDER BY reps DESC LIMIT 1
这条语句会筛选出指定exercise的所有行,按reps降序排列,然后只取第一行(也就是reps最大的那一行),返回的Cursor包含所有列信息。
第二步:正确读取Cursor中的数据
拿到正确的Cursor后,还要注意以下几点避免踩坑:
1. 严格匹配列名
你的数据库列名是_ID、excersise(注意拼写:是excersise不是exercise,少了一个c)、reps、timestamp,调用getColumnIndex()时必须完全匹配,大小写也要一致(SQLite默认不区分,但严格匹配更稳妥)。
2. 先验证列索引有效性
每次获取列索引后,先检查是否等于-1,确认列存在再读取数据。
3. 常规Cursor操作规范
- 使用前判断Cursor是否为null
- 调用
moveToFirst()确认有数据行 - 用完Cursor务必close,避免内存泄漏
下面是完整的代码示例(以Android SQLite为例):
// 替换成你的表名 String TABLE_NAME = "your_table_name"; // 替换成你要查询的目标运动名称 String targetExercise = "引体向上"; // 构建查询语句 String query = "SELECT * FROM " + TABLE_NAME + " WHERE excersise = ? ORDER BY reps DESC LIMIT 1"; Cursor cursor = db.rawQuery(query, new String[]{targetExercise}); if (cursor != null) { if (cursor.moveToFirst()) { // 获取各列索引,先检查有效性 int idIndex = cursor.getColumnIndex("_ID"); int exerciseIndex = cursor.getColumnIndex("excersise"); int repsIndex = cursor.getColumnIndex("reps"); int timestampIndex = cursor.getColumnIndex("timestamp"); if (idIndex != -1 && exerciseIndex != -1 && repsIndex != -1 && timestampIndex != -1) { // 读取数据并打印 long id = cursor.getLong(idIndex); String exercise = cursor.getString(exerciseIndex); int maxReps = cursor.getInt(repsIndex); long timestamp = cursor.getLong(timestampIndex); System.out.println(String.format("找到最大reps的行:ID=%d,运动=%s,次数=%d,时间戳=%d", id, exercise, maxReps, timestamp)); } else { System.err.println("错误:找不到指定列,请检查列名拼写是否正确!"); } } else { System.out.println("没有找到该运动的记录"); } // 关闭Cursor cursor.close(); } else { System.err.println("Cursor初始化失败"); }
最后再排查几个可能的细节
- 确认你的数据库表结构确实包含这四个列,没有拼写错误
- 如果用的是
query()方法而非rawQuery(),要确保投影参数(columns)没有漏掉需要的列 - 检查是否在查询时不小心过滤掉了需要的列
内容的提问来源于stack exchange,提问作者user9216568
相关产品推荐
相关产品推荐

