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

kmb7vmvb  于 2022-11-14  发布在  SQLite
关注(0)|答案(5)|浏览(158)

我花了几个小时的时间试图调试,为什么下面的删除查询实际上没有删除任何东西,即使完全相同的数据库上的相同查询在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);

由于连接和子查询都有点复杂,我的想法围绕着Android的SQLite实现对子查询的一些限制,所以我尝试简化查询。但它仍然没有删除任何东西。
然后,我将其更改为SELECT查询(只需将DELETE替换为SELECT*),这起作用了。因此,可能根本不是连接或子查询是罪魁祸首。
为了测试SELECT查询,我向返回的游标添加了一个moveToFirst()

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

当我后来再次将其更改为删除查询时,我忘记了删除moveToFirst(),然后它就起作用了!
它现在可以工作了,这很好,但我非常困惑为什么要移动光标才能真正删除任何东西。这是故意的,还是有漏洞?

rslzwgfq

rslzwgfq1#

我无法回答原因,但另一个解决方案是使用.execSQL(字符串),如发布的here所示

cedebl8k

cedebl8k2#

RawQuery返回结果集的游标,它只是对查询结果的引用。您应该只使用直接的DELETE()调用。请看一下文档:
http://developer.android.com/reference/android/database/sqlite/SQLiteDatabase.html
或SQLiteStatement:
http://developer.android.com/reference/android/database/sqlite/SQLiteStatement.html

1qczuiv0

1qczuiv03#

在我的例子中,删除也发生了同样的事情,它在调用“cursor.moveToFirst()”后成功运行。INSERT和UPDATE查询也一样。我还观察到,对于上述查询,调用游标上的任何方法都可以正确地获得结果。在不调用游标的任何方法的情况下,所需的效果正在发生。因此,我认为您的问题的答案是:只有当我们在游标上调用某个方法时,才会执行查询。

ujv3wf0j

ujv3wf0j4#

答案是因为rawQuery实际上不会执行,直到您对返回的游标调用某个方法。MoveToFirst,is AfterLast..

jdzmm42g

jdzmm42g5#

下面的示例显示了如果我们不需要编写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;
}

相关问题