sql >> Databáze >  >> RDS >> SQLite

Vložit nebo aktualizovat Android SQLite

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.



  1. Jak zobrazit výsledek/výstup rekurzoru v Oracle SQL Developer?

  2. Oracle SQL Injection Block s DBMS_ASSERT

  3. Mapování pole pomocí režimu spánku

  4. Dílčí dotazy SQL v kontrolním omezení