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

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.04 20:33:35