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