如何使用anko在Kotlin中删除除最新10条记录以外的所有记录?

7

代码B定义了一个日志表,我希望清除除最新10条记录以外的所有记录。

目前,我首先按CreatedDate列出所有记录,然后从第11条记录到最后一条记录循环,使用代码A删除记录。

在Kotlin中,使用anko有更好的方法吗?

代码A

fun deleteDBLogByID(_id:Long)=mDBLogHelper.use{
        delete(DBLogTable.TableNAME,"$idName = {$idName} ","$idName" to _id.toString() )
}

代码 B

class DBLogHelper(mContext: Context = UIApp.instance) : ManagedSQLiteOpenHelper(
        mContext,
        DB_NAME,
        null,
        DB_VERSION) {

    companion object {
        val DB_NAME = "log.db"
        val DB_VERSION = 1
        val instance by lazy { DBLogHelper() }
    }

    override fun onCreate(db: SQLiteDatabase) {
        db.createTable( DBLogTable.TableNAME , true,
                DBLogTable._ID to INTEGER + PRIMARY_KEY+ AUTOINCREMENT,
                DBLogTable.CreatedDate to INTEGER,
                DBLogTable.Status to INTEGER  +DEFAULT("0"),
                DBLogTable.Description to TEXT
        )
    } 

}

我不了解Kotlin,也不了解Anko...但是我了解Java。 - BiRjU
也许我建议你需要将它转换为 Kotlin。 - BiRjU
2个回答

3

请查看以下位置的源代码:

https://github.com/Kotlin/anko/blob/e388295c70963d97d26820d4ecdf48ead8dba05e/anko/library/static/sqlite/src/Database.kt#L73

该函数定义还需要一个whereClause参数。

fun SQLiteDatabase.delete(tableName: String, whereClause: String = "", vararg args: Pair<String, Any>): Int {
    return delete(tableName, applyArguments(whereClause, *args), null)
}

以下SO主题中也可以看到这一点

如何使用Anko删除SQLite中具有多个by where args的行?

现在结合上面和下面的SO主题

在SQL中从数据库表中删除除前n个以外的所有内容

WHERE id NOT IN (SELECT id FROM table ORDER BY id LIMIT n);

您可以像下面这样做:
delete(TABLE_NAME, whereClause = "WHERE _ID NOT IN (SELECT _ID FROM {TABLE_NAME} ORDER BY CreatedDate Desc LIMIT {TOP})", 
                                                "TOP" to 10,
                                                "TABLE_NAME" to TABLE_NAME)

如果上述方法不起作用,可能需要进行微调,但这种方法应该有效。我没有设置Kotlin来测试和确认是否相同。但是,如果您遇到问题,可以提供反馈。


谢谢!最新的anko似乎删除了关键字WhereClause。 - HelloCW
所以应该是 fun deleteOldAndKeepLatest(maxLogCountToKeep:Int)=mDBLogHelper.use{ delete(DBLogTable.TableNAME, "$idName NOT IN (SELECT $idName FROM {TABLE_NAME} ORDER BY CreatedDate Desc LIMIT {TOP})", "TOP" to maxLogCountToKeep, "TABLE_NAME" to DBLogTable.TableNAME) },对吗? - HelloCW

1
如果您想通过列表来更简洁地完成操作,可以尝试以下方法: list.filterIndexed({ index, _ -> index > 10 }).forEach { delete(it) }

不是一个好的选项,因为如果你有1M条记录,你会发出1M-10个查询,然后你还会将数据发送回客户端,而我们也不需要这些数据。由于我们不关心记录,删除操作应该在服务器端完成,使用一个不会带回任何数据的查询。 - Tarun Lalwani

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接