rawQuery 未使用 cursor.moveToFirst、android studio 更新数据库

rawQuery not updating database with cursor.moveToFirst, android studio

我在更新数据库时遇到了一些困难。基本上用户会将数据输入到两个不同的地方,所以我们得到

Name    | Letter  | Marks   
----------------------------
Dave    | Null    | 90
Dave    | A       | Null

应该变成

Dave    | A       | 90

但是,没有任何更新。当我在 SQLite 管理器中尝试查询时,该查询完美运行,所以我一定是错误地实现了游标。

    public void insertData(String name, int mark_column, String marks) {
        String [] columns = new String[] {COL_3, COL_4, COL_5};
        SQLiteDatabase db = this.getWritableDatabase();
        ContentValues contentValues = new ContentValues();
        contentValues.put(COL_2, name);
        contentValues.put(columns[mark_column], marks);
        db.replace(TABLE_NAME, null, contentValues);
        //The code above works as desired
        String sql = "SELECT NAME, GROUP_CONCAT(LETTER, ', ') AS LETTER," +
            "GROUP_CONCAT(MARKS, ', ') AS MARKS FROM " + TABLE_NAME + " GROUP BY NAME";
        //This query works in SQLite Manager
        Cursor c = db.rawQuery(sql, null);
        c.moveToFirst();
        while(c.moveToNext());
        c.close();
    }

我已经尝试了 c.moveToLast 的各种组合,没有 c.moveToNext,等等。这个方法在 Alert Dialog 的 onClick 中调用。

非常感谢任何帮助

关于游标:

我没有发现您的查询有任何问题。如果您的应用中没有 "seeing" 任何结果,可能是因为您实际上并未对结果执行任何操作。它们存在于内存中的 Cursor 对象中,仅此而已;如果您想查看任何内容,您必须将该数据绑定到某些 UI 组件,或将其转储到 logcat 或其他内容。

请注意,如果您要在 while 循环内添加代码,您将跳过光标的第一行,因为您将有一个 moveToFirst() 调用,紧接着是一个 moveToNext() 打电话。这就是我迭代 Cursor 的方式,它始终有效:

if (cusor != null) {
    try {
        for (cursor.moveToFirst(); !cursor.isAfterLast(); cursor.moveToNext()) {
            // do something with data in current row
        }
    } finally {
        cursor.close();
    }
}

关于更新:

您实际上并没有进行更新本身,您正在进行插入。 SQLiteDatabase.replace() 执行这条命令:

INSERT OR REPLACE INTO tableName(columns) VALUES (values);

仅当您对 table 有约束并且插入具有这些值的新行会违反该约束时,这才可以用作更新(描述了不同约束违规的确切处理 here).对于我怀疑您期望的约束类型,此操作将删除现有行并插入包含这些值的新行,但它不会将已删除行的值转移到新的一个。换句话说,如果您希望发生替换,则需要 all ContentValues 中的组合值。它不像 UPDATE,您可以在其中设置特定列的值。

您或许应该尝试做一个实际的 update。确保使用正确的 WHERE 子句,以便只更新重要的行。

我可能误解了您的方法,但描述使您看起来像是在插入两行,然后尝试更新 and/or 稍后将它们合并。这对我来说没有意义,而且我预见到一些错误,你会留下不完整的行,需要清理。在我看来,最好将代码结构化为一个 INSERT,此后的每个操作都是感兴趣行上的一个 UPDATE