2016-07-06 9 views
5

Bevor ich die Dokumentation gelesen habe, hätte ich erwartet, dass die Methode SQLiteDatabaseinsertOrThrow() eine Ausnahme ausgelöst hat, wenn die Einfügung nicht erfolgreich war.Android - Wann löst insertOrThrow() eine Ausnahme aus?

Jedoch sagt der documentation dass das Verfahren insertOrThrow()

die Zeilen-ID des neu eingefügten Zeile zurückgibt, oder -1, wenn ein Fehler

So aufgetreten ist, wenn er zurückkehrt -1 Wenn ein Fehler auftritt, unter welchen Umständen wird eine Ausnahme ausgelöst?

+0

Wenn Fehler auftreten, z. B. IO-Fehler, falscher Datensatz, geschlossener Cursor writed, nicht geschriebene Rechte schreiben, usw. Meistens, wenn irgendein Fehler auftritt, -1 (die keine Zeile betroffen war) wird die Information – Bonatti

Antwort

-1

Die Methode insertOrThrow() löst die Ausnahme aus und gibt -1 zurück. Auf diese Weise können Sie überprüfen, ob Ihre Anfrage erfolgreich war oder nicht. Wenn es eine -1 zurückgibt, wurde Ihre Aktion nicht abgeschlossen und Sie müssen herausfinden, was falsch gelaufen ist!

+1

gegeben 't' gibt -1 zurück ** und ** werfen gleichzeitig eine Ausnahme aus. Meine Frage ist also, wann es "-1" zurückgibt und wann es eine Ausnahme auslöst. –

0

Sie können die SQLiteDatabase source code nachschlagen, um zu sehen, wie es funktioniert. Es scheint, dass es eine SQLiteDatabaseCorruptException wirft, wenn die SQL-Zeichenfolge ungültig ist, andernfalls -1 zurückgeben.

+0

Die Ausnahme wird vom C++ - Code ausgelöst. –

+0

Können Sie erklären? Der Link in meinem Post zeigt die Methode an, nach der er fragt, die eine SQLiteDatabaseException für einen Aufruf von executeInsert auslöst. – bradkratky

+0

Die 'throws' Klausel gibt an, welche Ausnahmen die Funktion * can * werfen kann. Es gibt keine throw-Anweisung in dem Code, mit dem Sie verknüpft sind. –

3

Mein Verständnis ist, dass es -1 zurückgibt, wenn der gesamte Code ordnungsgemäß ausgeführt werden konnte und ein Fehler "EXPECTED" aufgetreten ist. Allerdings sind nicht alle Fehler/Ausnahmen behandelt und einige Ausnahmen noch ausgelöst werden können:

  • SQLiteDatabaseCorruptException
  • Illegal
  • Runtime
  • Datenbank für schreibgeschützte
  • geöffnet versucht, eine duplizierte einfügen Schlüssel

HERE Sie können die Implementierung vonfindenund insertOrThrow().

Sie können sehen, dass beide Methoden ähnlich sind. Jedoch insert() behandelt SQLException s für Sie. insertOrThrow() behandelt keine Ausnahme und Sie sollten es selbst tun.

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); 
} 

Beide Methoden nennt insertWithOnConflict() die Umsetzung ist 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(); 
    } 
} 

Bei der Umsetzung werden Sie sehen, dass es gibt „-1“ nur dann, wenn statement.executeInsert(); kehrt etwas (und es scheint, dass „-1 "kam von hier):

.../Frameworks/base/Kern/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; 
} 

Wenn ein anderer Fehler/Ausnahme in der Mitte auftritt, wird eine Ausnahme ausgelöst.

Wenn Sie den aufgerufenen Methoden folgen, können Sie sehen, dass andere Fehler nicht behandelt werden. Außerdem werden Sie feststellen, dass die SQLite tatsächlich von einer C-Task (und nicht von Java) ausgeführt wird. Daher können mehrere nicht erwartete Fehler weiterhin auftreten.

+0

Dies antwortet immer noch nicht, wenn genau "-1" zurückgegeben wird. 'executeNonQuery' gibt immer' SQLITE_DONE' zurück. –