Jeg tror, at du spørger, hvordan du INDSÆTTER nye rækker eller OPDATERINGER dine eksisterende rækker i ét trin. Selvom det er muligt i en enkelt rå SQL som diskuteret i dette svar, fandt jeg ud af, at det er nemmere at gøre dette i to trin i Android ved at bruge SQLiteDatabase.insertWithOnConflict() ved at bruge CONFLICT_IGNORE til konfliktalgoritme.
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
}
Dette eksempel forudsætter, at tabelnøglen er indstillet til kolonne "_id", at du kender posten _id, og at der allerede er række #1 (_id=1, columnA ="valueA", columnB ="valueB"). Her er forskellen ved at bruge insertWithOnConflict med CONFLICT_REPLACE og CONFLICT_IGNORE
- CONFLICT_REPLACE vil overskrive eksisterende værdier i andre kolonner til null (dvs. kolonne B bliver NULL og resultatet bliver _id=1, columnA ="valueNEW", columnB =NULL). Du mister eksisterende data som et resultat, og jeg bruger dem ikke i min kode.
- CONFLICT_IGNORE vil springe SQL INSERT over for din eksisterende række #1, og du vil SQL OPDATERE denne række i næste trin og bevare indholdet af alle andre kolonner (dvs. resultatet vil være _id=1, columnA ="valueNEW", kolonneB ="værdiB").
Når du forsøger at indsætte ny række #2, som ikke eksisterer endnu, vil koden kun udføre SQL INSERT i den første sætning insertWithOnConflict (dvs. resultatet vil være _id=2, columnA ="valueNEW", columnB =NULL).
Pas på denne fejl, som får SQLiteDatabase.CONFLICT_IGNORE til at fungere forkert på API10 (og sandsynligvis API11). Forespørgslen returnerer 0 i stedet for -1, når jeg tester på Android 2.2.
Hvis du ikke kender registreringsnøglen _id, eller hvis du har en tilstand, der ikke vil skabe en konflikt, kan du vende logikken til OPDATERING eller INDSÆT . Dette vil beholde din registreringsnøgle _id under UPDATE eller oprette et nyt 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);
}
Ovenstående eksempel forudsætter, at du for eksempel bare ønsker at OPDATERE tidsstempelværdien i posten. Hvis du kalder insertWithOnConflict først, vil INSERT oprette nyt record _id på grund af forskellen i tidsstemplets tilstand.