sql >> Databasteknik >  >> RDS >> SQLite

Android SQLite infoga eller uppdatera

Jag tror att du frågar hur du INSTÄLLAR nya rader eller UPPDATERINGAR dina befintliga rader i ett steg. Även om det är möjligt i en enda rå SQL som diskuteras i det här svaret, fann jag att det är lättare att göra detta i två steg i Android med SQLiteDatabase.insertWithOnConflict() med CONFLICT_IGNORE för conflictAlgorithm.

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
}

Det här exemplet förutsätter att tabellnyckeln är inställd för kolumn "_id", att du känner till posten _id och att det redan finns rad #1 (_id=1, kolumnA ="värdeA", kolumnB ="värdeB"). Här är skillnaden när du använder insertWithOnConflict med CONFLICT_REPLACE och CONFLICT_IGNORE

  • CONFLICT_REPLACE kommer att skriva över befintliga värden i andra kolumner till null (dvs. kolumn B blir NULL och resultatet blir _id=1, kolumnA ="valueNEW", kolumnB =NULL). Du förlorar befintlig data som ett resultat och jag använder den inte i min kod.
  • CONFLICT_IGNORE hoppar över SQL INSERT för din befintliga rad #1 och du kommer att SQL UPPDATERA denna rad i nästa steg och bevara innehållet i alla andra kolumner (dvs resultatet blir _id=1, columnA ="valueNEW", kolumnB ="värdeB").

När du försöker infoga ny rad #2 som inte existerar ännu, kommer koden endast att exekvera SQL INSERT i den första satsen insertWithOnConflict (dvs resultatet blir _id=2, columnA ="valueNEW", columnB =NULL).

Se upp för denna bugg som gör att SQLiteDatabase.CONFLICT_IGNORE inte fungerar på API10 (och förmodligen API11). Frågan returnerar 0 istället för -1 när jag testar på Android 2.2.

Om du inte känner till postnyckeln _id eller om du har ett tillstånd som inte skapar en konflikt kan du vända om logiken till UPPDATERA eller INFOGA . Detta kommer att behålla din postnyckel _id under UPDATE eller skapa ett nytt record _id under INSERT.

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

Exemplet ovan förutsätter att du till exempel bara vill UPPDATERA tidsstämpelvärdet i posten. Om du först anropar insertWithOnConflict kommer INSERT att skapa nytt post _id på grund av skillnaden i tidsstämpelns villkor.



  1. Jämför arrayer för likhet, ignorera ordningen av element

  2. Hur ändrar jag standardschemat i sql-utvecklare?

  3. SQL - Call Stored Procedure för varje post

  4. Hur får man numeriska typer från MySQL med PDO?