Android SQLite中getColumnIndex返回-1引发Value must be ≥0报错,如何修复?
Android SQLite "Value must be ≥ 0" 错误修复方案
问题根源
报错的核心原因是cursor.getColumnIndex(KEY_QTY)返回了-1,表示查询结果中不存在名为KEY_QTY的列,此时将-1传入cursor.getString()就会触发"Value must be ≥ 0"的参数非法错误。
修复方案
针对这个问题,我们可以从列索引校验和查询语句优化两个层面来修复:
1. 增加列索引有效性校验
在调用cursor.getString()之前,先判断列索引是否合法(≥0),避免无效索引传入方法:
public String CheckOrderExists(long recipe_id) { String _stringVal = "0"; SQLiteDatabase db = this.getWritableDatabase(); Cursor cursor = db.rawQuery("SELECT * FROM " + TABLE_ADDCART + " WHERE " + KEY_RECIPE_ID + " = ?", new String[]{String.valueOf(recipe_id)}); if (cursor.moveToFirst()) { int qtyColumnIndex = cursor.getColumnIndex(KEY_QTY); // 先校验列索引是否有效 if (qtyColumnIndex != -1) { _stringVal = cursor.getString(qtyColumnIndex); if (_stringVal.equals("0")) { db.execSQL("DELETE FROM " + TABLE_ADDCART + " WHERE " + KEY_RECIPE_ID + " = ?", new String[]{String.valueOf(recipe_id)}); } } // 如果列索引无效,保持默认值"0" } cursor.close(); db.close(); return _stringVal; }
2. 优化查询语句(推荐)
避免使用SELECT *查询所有列,而是明确指定需要的列(这里只需要KEY_QTY),这样不仅能确保查询结果中包含目标列,还能减少数据传输量,提升查询效率:
public String CheckOrderExists(long recipe_id) { String _stringVal = "0"; SQLiteDatabase db = this.getWritableDatabase(); // 明确指定查询KEY_QTY列,而非所有列 Cursor cursor = db.rawQuery("SELECT " + KEY_QTY + " FROM " + TABLE_ADDCART + " WHERE " + KEY_RECIPE_ID + " = ?", new String[]{String.valueOf(recipe_id)}); if (cursor.moveToFirst()) { // 因为查询语句明确包含KEY_QTY,这里可以直接用索引0(唯一列),或者仍用getColumnIndex做兼容 _stringVal = cursor.getString(0); if (_stringVal.equals("0")) { db.execSQL("DELETE FROM " + TABLE_ADDCART + " WHERE " + KEY_RECIPE_ID + " = ?", new String[]{String.valueOf(recipe_id)}); } } cursor.close(); db.close(); return _stringVal; }
额外建议
- 确保
KEY_QTY常量的值与数据库表TABLE_ADDCART中实际的列名完全一致(SQLite默认大小写不敏感,但部分设备可能存在差异)。 - 操作数据库时,建议使用
try-finally块确保Cursor和Database被正确关闭,避免资源泄漏:
public String CheckOrderExists(long recipe_id) { String _stringVal = "0"; SQLiteDatabase db = null; Cursor cursor = null; try { db = this.getWritableDatabase(); cursor = db.rawQuery("SELECT " + KEY_QTY + " FROM " + TABLE_ADDCART + " WHERE " + KEY_RECIPE_ID + " = ?", new String[]{String.valueOf(recipe_id)}); if (cursor.moveToFirst()) { _stringVal = cursor.getString(0); if (_stringVal.equals("0")) { db.execSQL("DELETE FROM " + TABLE_ADDCART + " WHERE " + KEY_RECIPE_ID + " = ?", new String[]{String.valueOf(recipe_id)}); } } } finally { if (cursor != null) { cursor.close(); } if (db != null) { db.close(); } } return _stringVal; }
内容的提问来源于stack exchange,提问作者jay raman
相关产品推荐
相关产品推荐

