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

时间:2016-07-06 13:50:12

标签: android sqlite android-database

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

但是,documentation表示insertOrThrow()方法

  

返回新插入行的行ID,如果发生错误则返回 -1

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

3 个答案:

答案 0 :(得分:3)

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

  • SQLiteDatabaseCorruptException
  • 抛出:IllegalArgumentException
  • 的RuntimeException
  • 数据库以只读方式打开
  • 尝试插入重复的密钥

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”来自此处):

... /框架/碱/核心/ 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)执行。因此,仍然可能发生一些非预期的错误。

答案 1 :(得分:0)

您可以查看SQLiteDatabase source code以查看其工作原理。如果SQL字符串无效,它似乎会抛出SQLiteDatabaseCorruptException,否则返回-1。

答案 2 :(得分:-1)

insertOrThrow()方法抛出异常并返回-1。通过这种方式,您可以检查您的查询是否成功。如果它返回-1你的行动没有完成,你需要弄清楚出了什么问题!