我使用 @RawQuery 在房间数据库中执行查询。但我找不到一种方法来以这种方式获取受影响的行。
我尝试了
SELECT changes() as affected_rows
并通过光标获取结果,但它总是返回零。
到目前为止我的代码(我在插入、更新、删除语句后运行此代码)。
val cursor = daoUnit.query(SimpleSQLiteQuery("SELECT CHANGES() AS affected_rows"))
var affectedRowCount = 0
cursor.use { innerCursor ->
val affectedRowColumn = innerCursor.getColumnIndex("affected_rows")
if (innerCursor.count > 0 && innerCursor.moveToFirst()){
affectedRowCount = innerCursor.getInt(affectedRowColumn)
Log.e("TAG", "AFFECTED ROW COUNT : $affectedRowCount")
}
}
我相信您在尝试使用
changes()
函数时不会有任何运气,这可能是由于代码的底层包装所致。
到目前为止我的代码(我在插入、更新、删除语句后运行此代码)
如果您使用便捷方法,即
@Insert
、@Update
或 @Delete
,那么这些返回值可用于确定更改数量。
@Update
和 @Delete
直接以 Int 形式返回受影响的行数。
@Insert
,如果在可以处理插入的多行的插入的情况下未插入行,则返回 rowid 或 -1,然后返回 rowid 或 -1 的数组。因此,可以通过返回来确定受影响的行数。
作为示例,请考虑以下代码:- 0
@Dao
带注释的界面中的一些功能:-
@Insert(onConflict = OnConflictStrategy.IGNORE)
fun insert(parent: List<Parent>): LongArray
@RawQuery
fun rq(sql: SupportSQLiteQuery): Cursor
@Query("INSERT INTO parent VALUES (100,'XP1'),(null,'XP2')")
fun insertViaSQL()
@Transaction
@Query("")
fun xxx() {
val result = insert(listOf(Parent(parent_name = "PARENT1"),Parent(parent_name = "PARENT2")))
DatabaseUtils.dumpCursor(rq(SimpleSQLiteQuery("SELECT changes() AS affected_rows")))
var skipped=0
var inserted = 0
for (r in result) {
if (r == -1L) skipped++ else inserted++
}
Log.d("DBINFO","Inserted ${inserted}. Skipped ${skipped}")
rq(SimpleSQLiteQuery("INSERT INTO parent VALUES (100,'XP1'),(null,'XP2')"))
DatabaseUtils.dumpCursor(rq(SimpleSQLiteQuery("SELECT changes() AS affected_rows")))
}
:-
val parents: ArrayList<Parent> = ArrayList()
val sql1: SupportSQLiteQuery = SimpleSQLiteQuery("SELECT CHANGES() AS affected_rows")
val sql2 = SimpleSQLiteQuery("SELECT (CHANGES()) AS affected_rows")
parents.add(Parent(parent_name = "P1"))
parents.add(Parent(parent_name = "P2"))
parents.add(Parent(parent_name = "P3"))
parents.add(Parent(parent_name = "P4"))
parents.add(Parent(1,"rowid 1 would likely already exist"))
val result = dao.insert(parents)
var skipped=0
var inserted=0
for (rslt in result) {
if (rslt == -1L) skipped++ else inserted++
}
Log.d("DBINFO","Inserted ${inserted}, Skipped ${skipped}")
insertViaSQL()
val csr = dao.rq(sql1)
DatabaseUtils.dumpCursor(csr)
DatabaseUtils.dumpCursor(dao.rq(sql2))
dao.xxx()
@Insert
方法。这是原始 SQL,不会返回任何结果。但是,由于 Room 确定不会返回任何结果,因此不会执行原始查询。@RawQuery
可以看出,
2024-09-24 15:55:19.159 D/DBINFO: Inserted 4, Skipped 1
2024-09-24 15:55:19.159 I/System.out: >>>>> Dumping cursor android.database.sqlite.SQLiteCursor@649c946
2024-09-24 15:55:19.160 I/System.out: 0 {
2024-09-24 15:55:19.160 I/System.out: affected_rows=0
2024-09-24 15:55:19.160 I/System.out: }
2024-09-24 15:55:19.160 I/System.out: <<<<<
2024-09-24 15:55:19.160 I/System.out: >>>>> Dumping cursor android.database.sqlite.SQLiteCursor@ae23707
2024-09-24 15:55:19.161 I/System.out: 0 {
2024-09-24 15:55:19.161 I/System.out: affected_rows=0
2024-09-24 15:55:19.161 I/System.out: }
2024-09-24 15:55:19.161 I/System.out: <<<<<
2024-09-24 15:55:19.180 I/System.out: >>>>> Dumping cursor android.database.sqlite.SQLiteCursor@57fc034
2024-09-24 15:55:19.180 I/System.out: 0 {
2024-09-24 15:55:19.180 I/System.out: affected_rows=0
2024-09-24 15:55:19.180 I/System.out: }
2024-09-24 15:55:19.180 I/System.out: <<<<<
2024-09-24 15:55:19.180 D/DBINFO: Inserted 2. Skipped 0
2024-09-24 15:55:19.182 I/System.out: >>>>> Dumping cursor android.database.sqlite.SQLiteCursor@2cde5d
2024-09-24 15:55:19.182 I/System.out: 0 {
2024-09-24 15:55:19.182 I/System.out: affected_rows=0
2024-09-24 15:55:19.182 I/System.out: }
2024-09-24 15:55:19.182 I/System.out: <<<<<
的返回值(LongArray)可用于确定受影响的行数。但是,
@Insert
内置函数在任何时候都不会返回 0 以外的值,即使在与后者插入尝试相同的事务中也是如此。显然 changes()
和
@Delete
更简单,因为返回的是受影响的行数。