首页 > 解决方案 > execSQL能否支持多条sql语句

问题描述

execSQL 可以支持多个语句还是我应该执行单独的命令。我的用例是在事务的上下文中。

fun update(id: Long, roles: List<Role>): Int? {
    val values = (roles.map { role -> "($id, ${role.id})" }).joinToString(",")

    val sql = "BEGIN TRANSACTION; DELETE FROM user_role WHERE user_id = $id;" + (if (values.count() > 0) "INSERT INTO user_role(user_id, role_id) VALUES$values; " else "") + "COMMIT;"

    connection.writableDatabase.execSQL(sql)

    return connection.readableDatabase.rawQuery("SELECT changes()", null).use { cursor ->
        return@use cursor.count
    }
}

可行的替代方法如下。

fun update(id: Long, roles: List<Role>): Int? {
    val values = (roles.map { role -> "($id, ${role.id})" }).joinToString(",")

    connection.writableDatabase.execSQL("BEGIN TRANSACTION;")
    connection.writableDatabase.execSQL("DELETE FROM user_role WHERE user_id = $id;")

    if (values.count() > 0) connection.writableDatabase.execSQL("INSERT INTO user_role(user_id, role_id) VALUES$values")
    connection.writableDatabase.execSQL("COMMIT")

    return connection.readableDatabase.rawQuery("SELECT changes()", null).use { cursor ->
        return@use cursor.count
    }
}

尝试捕捉方法

fun update(id: Long, roles: List<Role>): Int? {
    try {
        connection.writableDatabase.execSQL("BEGIN TRANSACTION;")
        connection.writableDatabase.execSQL("DELETE FROM user_role WHERE user_id = $id;")

        val values = (roles.map { role -> "($id, ${role.id})" }).joinToString(",")

        if (values.count() > 0) connection.writableDatabase.execSQL("INSERT INTO user_role(user_id, role_id) VALUES$values")
        connection.writableDatabase.execSQL("COMMIT") 
    } catch(exception: Exception) {
        connection.writableDatabase.execSQL("ROLLBACK")
        return null
    }

    return connection.readableDatabase.rawQuery("SELECT changes()", null).use { cursor ->
        return@use cursor.count
    }
}

标签: androidsqlite

解决方案


没有。

execSQL()只执行单个语句。第一个之后的任何内容都将;被忽略。


好的,是否已知 execSQL 会抛出错误,以防万一出现问题以便我可以执行回滚,我应该将它包含在 try catch 块中吗?

是的,它可以抛出异常。事务的规范模式类似于(Java,但在 Kotlin 中的想法是相同的):

db.beginTransaction();
try {
    // db operations that can throw and should be executed atomically

    db.setTransactionSuccessful();
} finally {
    db.endTransaction();
}

这个想法是endTransaction()回滚,除非在 try 块结束时将事务设置为成功。


推荐阅读