Android - insertOrThrow() 什么时候抛出异常?

标签 android sqlite android-database

在阅读文档之前,我会期望 SQLiteDatabaseinsertOrThrow() 方法在插入不成功时抛出异常。

然而,documentation表示 insertOrThrow() 方法

returns the row ID of the newly inserted row, or -1 if an error occurred

那么,如果它在出错时返回-1,那么它在什么情况下会抛出异常呢?

最佳答案

我的理解是,如果所有代码都可以正确执行并且发生“EXPECTED”错误,它将返回-1。然而,并不是所有的错误/异常都被处理,一些异常仍然可能被触发:

  • SQLiteDatabaseCorruptException
  • 非法参数异常
  • 运行时异常
  • 数据库以只读方式打开
  • 尝试插入重复的 key

HERE您可以找到 insert()insertOrThrow() 的实现。

你可以看到这两种方法是相似的。但是,insert() 会为您处理 SQLExceptioninsertOrThrow() 不处理任何异常,你应该自己做。

public long insert(String table, String nullColumnHack, ContentValues values) {
    try {
        return insertWithOnConflict(table, nullColumnHack, values, CONFLICT_NONE);
    } catch (SQLException e) {
        Log.e(TAG, "Error inserting " + values, e);
        return -1;
    }
}

public long insertOrThrow(String table, String nullColumnHack, ContentValues values)
        throws SQLException {
    return insertWithOnConflict(table, nullColumnHack, values, CONFLICT_NONE);
}

这两种方法都调用 insertWithOnConflict() 实现是 HERE :

public long insertWithOnConflict(String table, String nullColumnHack,
        ContentValues initialValues, int conflictAlgorithm) {
    acquireReference();
    try {
        // CODE
        try {
            // ONLY HERE I return some value.... Otherwise, I'll raise an exception
            return statement.executeInsert();
        } finally {
            statement.close();
        }
    } finally {
        releaseReference();
    }
}

在实现中,您会看到它仅在 statement.executeInsert(); 返回某些内容时才返回“-1”(似乎“-1”来自此处):

.../frameworks/base/core/jni/android_database_SQLiteConnection.cpp

static jlong nativeExecuteForLastInsertedRowId(JNIEnv* env, jclass clazz,
        jlong connectionPtr, jlong statementPtr) {
    SQLiteConnection* connection = reinterpret_cast<SQLiteConnection*>(connectionPtr);
    sqlite3_stmt* statement = reinterpret_cast<sqlite3_stmt*>(statementPtr);

    int err = executeNonQuery(env, connection, statement);
    return err == SQLITE_DONE && sqlite3_changes(connection->db) > 0
            ? sqlite3_last_insert_rowid(connection->db) : -1;
}

如果中间发生任何其他错误/异常,则会抛出异常。

如果按照调用的方法进行操作,您会发现其他错误未得到处理。此外,您会注意到 SQLite 实际上将由 C 任务(而不是 java)执行。所以,一些非预期的错误仍然会发生。

关于Android - insertOrThrow() 什么时候抛出异常?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38225725/

相关文章:

c# - EF7错误插入默认日期

android - 你能改变 SQLite (Android) 中的 _id autoincrement 字段吗?

android - 使用支持库时如何在 ListView 中提供 ContextMenu?

c++ - 获取sqlite3中的列名

android - "exist"附近的 SQLite 故障

android - 为聊天模型定义房间实体之间的一对多关系

android - 运行此 AVD 需要 Intel HAXM

java - 画完 Canvas 后如何使 Canvas 变白?

java - 如何防止数据库关闭后线程继续运行?

android - Firebase 权限被拒绝错误