Credo che tu stia chiedendo come INSERIRE nuove righe o AGGIORNA le righe esistenti in un solo passaggio. Mentre ciò è possibile in un singolo SQL raw come discusso in this answer, ho trovato che è più facile farlo in due passaggi in Android utilizzando SQLiteDatabase.insertWithOnConflict() utilizzando CONFLICT_IGNORE per 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
}
Questo esempio presuppone che la chiave tavola è apparecchiata per la colonna "_id", che si conosce il _id record e che c'è già riga 1 # (_ID = 1, Columna = "valoreA", ColumnB = "valoreB"). Qui è la differenza utilizzando insertWithOnConflict con CONFLICT_REPLACE e CONFLICT_IGNORE
- CONFLICT_REPLACE sovrascrive valori esistenti in altre colonne null (es. ColumnB diventerà NULL e il risultato sarà _ID = 1, columna = "valueNEW", ColumnB = NULLO). Si perdono i dati esistenti come risultato e io non li uso nel mio codice.
- CONFLICT_IGNORE salterà SQL INSERT per la riga 1 esistente e SQL AGGIORNA questa riga nel passaggio successivo, preservando il contenuto di tutte le altre colonne (ad esempio, il risultato sarà _id = 1, columnA = "valoreNEW", columnB = "valoreB").
Quando si tenta di inserire nuova riga # 2, che ancora non esiste, il codice verrà eseguito solo l'INSERT SQL nel insertWithOnConflict prima istruzione (cioè. Il risultato sarà _ID = 2, Columna = "valoreA" colonnaB = NULL).
Attenzione da this bug che causa il malfunzionamento di SQLiteDatabase.CONFLICT_IGNORE su API10 (e probabilmente su API11). La query restituisce 0 anziché -1 quando eseguo il test su Android 2.2.
Se non si conosce la chiave di registrazione _id o si ha una condizione che non creerà un conflitto, è possibile invertire la logica in UPDATE o INSERISCI. Ciò manterrà la chiave di record _id durante UPDATE o creerà un nuovo record _id durante INSERT.
int u = yourdb.update("yourtable", values, "anotherID=?", new String[]{"x"});
if (u == 0) {
yourdb.insertWithOnConflict("yourtable", null, values, SQLiteDatabase.CONFLICT_REPLACE);
}
L'esempio precedente presuppone che si desideri solo aggiornare il valore di data/ora nel record, ad esempio. Se si chiama insertWithOnConflict per primo, INSERT creerà un nuovo record _id a causa della differenza nella condizione di timestamp.
Si potrebbe chiamare aggiornamento su una riga particolare .. Es. aggiorna ___ dove rowId = 4 .. e se l'aggiornamento restituisce 0 .. sai che non hai quella riga, quindi basta inserirla. – dymmeh