SQLite
 sql >> Base de Dados >  >> RDS >> SQLite

Inserção ou atualização do Android SQLite


Acredito que você esteja perguntando como INSERIR novas linhas ou ATUALIZAR suas linhas existentes em um passo. Embora isso seja possível em um único SQL bruto, conforme discutido nesta resposta, descobri que é mais fácil fazer isso em duas etapas no Android usando SQLiteDatabase.insertWithOnConflict() usando CONFLICT_IGNORE para 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
}

Este exemplo pressupõe que a chave da tabela está definida para a coluna "_id", que você conhece o registro _id e que já existe a linha #1 (_id=1, columnA ="valueA", columnB ="valueB"). Aqui está a diferença usando insertWithOnConflict com CONFLICT_REPLACE e CONFLICT_IGNORE
  • CONFLICT_REPLACE substituirá os valores existentes em outras colunas para nulo (ou seja, colunaB se tornará NULL e o resultado será _id=1, colunaA ="valorNEW", colunaB =NULL). Você perde os dados existentes como resultado e eu não os uso no meu código.
  • CONFLICT_IGNORE irá pular o SQL INSERT para sua linha existente nº 1 e você irá SQL UPDATE esta linha na próxima etapa preservando o conteúdo de todas as outras colunas (ou seja, o resultado será _id=1, columnA ="valueNEW", colunaB ="valorB").

Quando você tenta inserir uma nova linha #2 que ainda não existe, o código só executará o SQL INSERT na primeira instrução insertWithOnConflict (ou seja, o resultado será _id=2, columnA ="valueNEW", columnB =NULL).

Cuidado com este bug que está causando o mau funcionamento do SQLiteDatabase.CONFLICT_IGNORE na API10 (e provavelmente na API11). A consulta está retornando 0 em vez de -1 quando testo no Android 2.2.

Se você não souber a chave de registro _id ou tiver uma condição que não criará um conflito, você pode inverter a lógica para UPDATE ou INSERT . Isso manterá sua chave de registro _id durante UPDATE ou criará um novo registro _id durante INSERT.
int u = yourdb.update("yourtable", values, "anotherID=?", new String[]{"x"});
if (u == 0) {
    yourdb.insertWithOnConflict("yourtable", null, values, SQLiteDatabase.CONFLICT_REPLACE);
}

O exemplo acima supõe que você deseja apenas ATUALIZAR o valor do carimbo de data/hora no registro, por exemplo. Se você chamar insertWithOnConflict primeiro, INSERT criará um novo registro _id devido à diferença na condição de carimbo de data/hora.