首页 > 解决方案 > SQLite DELETE 查询在 moveToFirst() 上冻结

问题描述

我正在尝试在 Android 应用程序中删除 SQLite 数据库中的行。

这是查询和调用它的 Java 代码:

final Cursor cursor = mDb.rawQuery("DELETE FROM link WHERE version!=? AND sentence IN (SELECT _id FROM sentence WHERE language=?) AND translation IN (SELECT _id FROM sentence WHERE language=?)", new String[]{String.valueOf(versionToConserve), sentenceLanguage, translationLanguage});
cursor.moveToFirst();
cursor.close();

应用程序在 cursor.moveToFirst() 上冻结。

这是EXPLAIN QUERY PLAN

selectid:0, order:0, from:0, detail:SEARCH TABLE link USING INDEX sqlite_autoindex_link_1 (sentence=? AND translation=?),
selectid:0, order:0, from:0, detail:EXECUTE LIST SUBQUERY 0,
selectid:0, order:0, from:0, detail:SCAN TABLE sentence,
selectid:0, order:0, from:0, detail:EXECUTE LIST SUBQUERY 1,
selectid:1, order:0, from:0, detail:SCAN TABLE sentence, 

我以为查询可能太慢了,但是半个小时后,它仍然卡在这里。

我试图用 替换DELETESELECT它也冻结了。

SELECT我单独尝试了内部查询,它们运行良好。

我试图SELECT用(1,2,3)和(4,5,6)替换内部查询,它有效。

我尝试使用JOIN而不是,IN (SELECT ...)但它不接受它。它说LIMITWHERE或者其他条款是预期的,而不是JOIN

我不知道如何进一步调查。有任何想法吗?

标签: javaandroidsqliteandroid-sqlite

解决方案


不要rawQuery()用于删除行。
该方法rawQuery()用于以 a 的形式返回带有SELECT语句的行Cursor

使用delete()

String strWhere = "version <> ? AND " +
                  "sentence IN (SELECT _id FROM sentence WHERE language = ?) AND " +
                  "translation IN (SELECT _id FROM sentence WHERE language = ?)";
int rows = mDB.delete(
    "link", 
    strWhere, 
    new String[]{String.valueOf(versionToConserve), sentenceLanguage, translationLanguage}
);

delete()分配给变量的返回值rows包含已删除的行数。


推荐阅读