2011-08-26 141 views
20

我一直在挣扎了几个小时试图调试为什么下面的删除查询居然没有删除任何东西,即使完全相同的数据库上完全相同的查询在Firefox” SQLite的经理工作得很好:为什么删除rawQuery需要moveToFirst才能真正删除行?

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 * DELETE)和工作。所以可能这不是连接或子查询毕竟是罪魁祸首。

为了测试选择查询我又增加了一个moveToFirst()返回的光标:

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

当我后来又变回删除查询,我忘了删除moveToFirst(),然后成功了!

真的很高兴,现在的工作,但我很困惑,为什么有必要来移动光标,以实际删除任何东西。这是设计还是错误?

+0

我刚刚杀了4小时对这个愚蠢的一个**的问题,他们应该有这样的文件中明确提出,时间真是浪费。 – LuckyMe

+0

我喜欢你的问题如何包含我的删除问题的答案,非常有效! – Noumenon

+0

感谢您的发现。这应该一定要记录!我认为不应该是这样,但至少现在起作用。 – kgrevehagen

回答

10

我不能回答为什么,但另一种解决方案是使用.execSQL(字符串)张贴here

5

甲rawQuery返回结果集,这仅仅是对查询结果的参考的光标。你应该直接使用直接delete()调用。看看文档:

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

或SQLiteStatement:

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

+0

如果可能,我会使用直接删除查询,但它不支持这样复杂的sql语句。至少据我所知,它不能在连接和子查询上操作。 – marlar

+0

然后使用我建议的第二个选项。 – SBerg413

+0

我当然会看看这个选项,但我仍然很好奇为什么需要moveToFirst。我见过很多使用rawQuery执行删除查询的例子,而且他们都没有使用moveToFirst。 – marlar

4

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

3

答案,就是因为rawQuery实际上并不执行直到ü呼吁恢复光标一些方法。 moveToFirst,isAfterLast ..

+0

与旧的答案有什么不同?你刚刚复制了@mopurizwarriors单词。 – Androiderson

+0

请再次仔细阅读...这不是关于成功或不成功。它根本不运行,但在执行游标上的某些方法之前准备查询。此外,这并不是尝试/失败的方法来确定答案,但表示它的意思是这样工作。 – Ewoks

+1

然后,你应该详细说明你的答案,因为**只有当我们调用光标**上的一些方法时,才会执行查询**并且** rawQuery实际上不会执行,直到调用返回的游标上的某个方法**读取同一个家伙。任何人都会说你刚刚复制,因为你的答案是2岁。 – Androiderson