我一直在努力调试为什么以下删除查询实际上没有删除任何内容,即使完全相同的数据库上的完全相同的查询在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()
,然后它才有效!
它现在很好用,但我很困惑为什么有必要移动光标以实际删除任何东西。这是设计还是错误?
答案 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;
}