为什么删除rawQuery需要moveToFirst才能实际删除行?

时间:2011-08-26 22:29:16

标签: android sqlite

我一直在努力调试为什么以下删除查询实际上没有删除任何内容,即使完全相同的数据库上的完全相同的查询在Firefox的SQLite管理器中正常工作:

String deleteSql = "DELETE FROM showsummary WHERE url IN (SELECT url FROM showsummary JOIN article_categories USING (url) WHERE categoryid=20 AND title LIKE 'page=%')";
mDb.rawQuery(deleteSql, null);

由于JOIN和子查询都有点复杂,我的想法围绕Android的sqlite实现中关于子查询的一些限制,所以我尝试简化查询。但它仍然没有删除任何东西。

然后我把它改成了一个select查询(只用SELECT *替换了DELETE)并且有效。所以可能不是连接或子查询毕竟是罪魁祸首。

为了测试select查询,我在返回的游标中添加了moveToFirst()

mDb.rawQuery(deleteSql, null).moveToFirst();

当我稍后再将其更改回删除查询时,我忘记删除moveToFirst() ,然后它才有效!

它现在很好用,但我很困惑为什么有必要移动光标以实际删除任何东西。这是设计还是错误?

5 个答案:

答案 0 :(得分:12)

我无法回答原因,但另一种解决方案是使用.execSQL(String)作为发布here

答案 1 :(得分:5)

rawQuery返回结果集的Cursor,它只是对查询结果的引用。你应该只是使用直接的delete()调用。看一下文档:

http://developer.android.com/reference/android/database/sqlite/SQLiteDatabase.html

或SQLiteStatement:

http://developer.android.com/reference/android/database/sqlite/SQLiteStatement.html

答案 2 :(得分:4)

在我的情况下,DELETE也发生了同样的事情,它在调用“cursor.moveToFirst()”后成功运行。 INSERT和UPDATE查询的情况也是如此。我还观察到,在上述查询的光标上调用任何方法我都能正确得到结果。在不调用光标的任何方法的情况下,正在发生期望的效果。所以,我认为你的问题的答案是:只有当我们在游标上调用某个方法时才会执行查询。

答案 3 :(得分:3)

答案为什么是因为rawQuery实际上没有执行直到你在返回的游标上调用一些方法。 moveToFirst,isAfterLast ..

答案 4 :(得分:0)

下面的示例显示了在我们不需要编写moveToFirst()的情况下如何通过rawQuery返回游标。

public Cursor deleteContact(int id) {
    SQLiteDatabase db = this.getWritableDatabase();
    db.delete(TABLE_CONTACTS, KEY_ID + " = ?",new String[]{String.valueOf(id)});
    Cursor c = db.rawQuery("DELETE FROM "+TABLE_CONTACTS+" WHERE "+KEY_ID+" = "+id,null);
    db.close();

    //if we not return Type Cursor then in above code:
    // db.rawQuery("DELETE FROM "+TABLE_NAME+" WHERE "+KEY_ID+" = "+id,null).moveToFirst();
    // in this way no return Type necessary.
    return c;
}