Domnívám se, že se ptáte, jak VLOŽIT nové řádky nebo AKTUALIZOVAT stávající řádky v jednom kroku. I když je to možné v jediném surovém SQL, jak je diskutováno v této odpovědi, zjistil jsem, že je snazší to udělat ve dvou krocích v Androidu pomocí SQLiteDatabase.insertWithOnConflict() pomocí CONFLICT_IGNORE pro konfliktní algoritmus.
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
}
Tento příklad předpokládá, že klíč tabulky je nastaven pro sloupec "_id", že znáte záznam _id a že již existuje řádek č. 1 (_id=1, sloupecA ="hodnotaA", sloupecB ="hodnotaB"). Zde je rozdíl při použití insertWithOnConflict s CONFLICT_REPLACE a CONFLICT_IGNORE
- CONFLICT_REPLACE přepíše stávající hodnoty v jiných sloupcích na hodnotu null (tj. sloupec B se změní na hodnotu NULL a výsledek bude _id=1, sloupecA ="hodnotaNEW", sloupecB =NULL). V důsledku toho ztratíte stávající data a já je nepoužiji ve svém kódu.
- CONFLICT_IGNORE přeskočí SQL INSERT pro váš stávající řádek č. 1 a v dalším kroku tento řádek SQL AKTUALIZUJETE, přičemž zachováte obsah všech ostatních sloupců (tj. výsledek bude _id=1, sloupecA ="valueNEW", sloupecB ="hodnotaB").
Když se pokusíte vložit nový řádek #2, který ještě neexistuje, kód provede pouze SQL INSERT v prvním příkazu insertWithOnConflict (tj. výsledek bude _id=2, sloupecA ="hodnotaNEW", sloupecB =NULL).
Dejte si pozor na tuto chybu, která způsobuje poruchu SQLiteDatabase.CONFLICT_IGNORE na API10 (a pravděpodobně API11). Když testuji na Androidu 2.2, dotaz vrací 0 místo -1.
Pokud neznáte klíč záznamu _id nebo máte podmínku, která nevyvolá konflikt, můžete obrátit logiku na UPDATE nebo INSERT . Tím se zachová váš klíč záznamu _id během UPDATE nebo se vytvoří nový záznam _id během INSERT.
int u = yourdb.update("yourtable", values, "anotherID=?", new String[]{"x"});
if (u == 0) {
yourdb.insertWithOnConflict("yourtable", null, values, SQLiteDatabase.CONFLICT_REPLACE);
}
Výše uvedený příklad předpokládá, že například chcete AKTUALIZOVAT hodnotu časového razítka v záznamu. Pokud nejprve zavoláte insertWithOnConflict, INSERT vytvoří nový záznam _id kvůli rozdílu v podmínce časového razítka.