SQLite
 sql >> Datenbank >  >> RDS >> SQLite

Android SQLite einfügen oder aktualisieren

Ich glaube, Sie fragen, wie Sie neue Zeilen einfügen oder Ihre vorhandenen Zeilen aktualisieren können in einem Schritt. Während dies in einem einzigen Roh-SQL möglich ist, wie in dieser Antwort besprochen, fand ich, dass es einfacher ist, dies in zwei Schritten in Android mit SQLiteDatabase.insertWithOnConflict() und CONFLICT_IGNORE für conflictAlgorithm zu tun.

ContentValues initialValues = new ContentValues();
initialValues.put("_id", 1); // the execution is different if _id is 2
initialValues.put("columnA", "valueNEW");

int id = (int) yourdb.insertWithOnConflict("your_table", null, initialValues, SQLiteDatabase.CONFLICT_IGNORE);
if (id == -1) {
    yourdb.update("your_table", initialValues, "_id=?", new String[] {"1"});  // number 1 is the _id here, update to variable for your code
}

Dieses Beispiel geht davon aus, dass der Tabellenschlüssel für die Spalte „_id“ gesetzt ist, dass Sie den Datensatz _id kennen und dass es bereits Zeile #1 gibt (_id=1, SpalteA =„WertA“, SpalteB =„WertB“). Hier ist der Unterschied bei der Verwendung von insertWithOnConflict mit CONFLICT_REPLACE und CONFLICT_IGNORE

  • CONFLICT_REPLACE wird vorhandene Werte in anderen Spalten auf Null überschreiben (dh SpalteB wird NULL und das Ergebnis ist _id=1, SpalteA ="valueNEW", SpalteB =NULL). Sie verlieren dadurch vorhandene Daten und ich verwende sie nicht in meinem Code.
  • CONFLICT_IGNORE überspringt das SQL INSERT für Ihre vorhandene Zeile #1 und Sie werden diese Zeile im nächsten Schritt per SQL UPDATE aktualisieren, wobei der Inhalt aller anderen Spalten beibehalten wird (d. h. das Ergebnis ist _id=1, columnA ="valueNEW", SpalteB ="WertB").

Wenn Sie versuchen, eine neue Zeile #2 einzufügen, die noch nicht existiert, führt der Code nur den SQL INSERT in der ersten Anweisung insertWithOnConflict aus (d. h. das Ergebnis ist _id=2, SpalteA ="WertNEW", SpalteB =NULL).

Hüten Sie sich vor diesem Fehler, der zu einer Fehlfunktion von SQLiteDatabase.CONFLICT_IGNORE auf API10 (und wahrscheinlich API11) führt. Die Abfrage gibt 0 statt -1 zurück, wenn ich auf Android 2.2 teste.

Wenn Sie den Datensatzschlüssel _id nicht kennen oder eine Bedingung vorliegt, die keinen Konflikt verursacht, können Sie die Logik in UPDATE oder INSERT umkehren . Dadurch wird Ihr Datensatzschlüssel _id während UPDATE beibehalten oder ein neuer Datensatz _id während INSERT erstellt.

int u = yourdb.update("yourtable", values, "anotherID=?", new String[]{"x"});
if (u == 0) {
    yourdb.insertWithOnConflict("yourtable", null, values, SQLiteDatabase.CONFLICT_REPLACE);
}

Das obige Beispiel geht davon aus, dass Sie beispielsweise nur den Zeitstempelwert im Datensatz AKTUALISIEREN möchten. Wenn Sie insertWithOnConflict zuerst aufrufen, erstellt INSERT aufgrund des Unterschieds in der Zeitstempelbedingung einen neuen Datensatz _id.