JavascriptProva

Visualizzazione post con etichetta unique. Mostra tutti i post
Visualizzazione post con etichetta unique. Mostra tutti i post

sabato 26 novembre 2016

Database SQLite: ottenere record unici per un campo o per una combinazione di campi.

Ho re-imparato come rendere unici i records di un database, rendendo unico il valore di un campo e rendendo unica una combinazione di valori di campi.

Rendere unico il valore di un singolo campo:
public class Helper extends SQLiteOpenHelper {
    public Helper(Context context) {
        super(context, "database.db",null,1);
    }

    @Override
    public void onCreate(SQLiteDatabase db) {
        db.execSQL("CREATE TABLE NOMI(_ID INTEGER PRIMARY KEY, " +
                "NOME TEXT NOT NULL UNIQUE, COGNOME TEXT)");
    }

    public void save(String nome, String cognome){
        SQLiteDatabase db=this.getWritableDatabase();
        ContentValues values=new ContentValues();
        values.put("NOME", nome);
        values.put("COGNOME", cognome);
        try {
            db.insertOrThrow("NOMI", null, values);
        }catch(Exception e){
            System.out.println("ERRORE");
        }
    }
Per avere una gestione dell'errore devo usare insertOrThrow in luogo di insert.

Ora provo a inserire due records con il nome uguale.
        helper=new Helper(this);
        helper.save("Mario","Rossi");
        helper.save("Mario","Bianchi");
    }
}
11-26 17:55:24.511 31319-31319/? I/System.out: ERRORE

e il database contiene solo il primo record.
Rendere unico il valore di una combinazione di campi:
    @Override
    public void onCreate(SQLiteDatabase db) {
        db.execSQL("CREATE TABLE NOMI(_ID INTEGER PRIMARY KEY, " +
                "NOME TEXT, COGNOME TEXT, UNIQUE(NOME, COGNOME))");
    }

    public void save(String nome, String cognome){
        SQLiteDatabase db=this.getWritableDatabase();
        ContentValues values=new ContentValues();
        values.put("NOME", nome);
        values.put("COGNOME", cognome);
        try {
            db.insertOrThrow("NOMI", null, values);
        }catch(Exception e){
            System.out.println("ERRORE");
        }
    }
Ora riprovo a inserire i due record di prima con solo il nome uguale:
    Helper helper;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        helper=new Helper(this);
        helper.save("Mario","Rossi");
        helper.save("Mario","Bianchi");
    }
}
Nessuna segnalazione di errore:


...e la tabella del database contiene tutti e due i records.

Ora provo a inserire due record uguali per nome e per cognome:
    Helper helper;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        helper=new Helper(this);
        helper.save("Mario","Rossi");
        helper.save("Mario","Rossi");
    }
}
11-26 18:02:17.103 3062-3062/? I/System.out: ERRORE

...e il database contiene solo il primo record.

Ora vorrei un'altra funzione: cercare un record sul database, se presente restituire l'id, se assente inserire il nuovo dato.
Si potrebbe gestire con le funzioni di cui sopra...

lunedì 22 febbraio 2016

Catch SQLiteConstraintException.

Ho scoperto finalmente come impedire l'interruzione del programma quando si verifichi il tentativo di un reinserimento nel database in un campo UNIQUE.
Avevo già incontrato in passato il problema di non riuscire a intercettare le eccezioni lanciate quando si tenti di inserire un duplicato in un campo UNIQUE, ma non ero riuscito a trovare la soluzione in rete e così ero ricorso a complicati mezzi cervellotici per ottenere questo risultato.
Adesso, invece, basta intercettare l'eccezione lanciata mediante il metodo insertOrThrow e gestirla eventualmente con un codice alternativo senza che si interrompa l'esecuzione del programma.
Ecco il codice completo:
 public void salva(String nome){
  SQLiteDatabase db=this.getWritableDatabase();
  ContentValues values=new ContentValues();
  values.put("nome", nome);
  try{
   db.insertOrThrow("tabella", null, values);
  }catch(SQLiteConstraintException e){
   Log.d("Exception", "Caught");
  }
 }
Ecco il risultato in LogCat:
02-22 19:25:39.944: E/SQLiteLog(12396): (2067) abort at 11 in [INSERT INTO tabella(nome) VALUES (?)]: UNIQUE constraint failed: tabella.nome
02-22 19:25:39.944: D/Exception(12396): Caught
02-22 19:25:39.944: V/LETTURA(12396): DATABASE
02-22 19:25:39.945: V/1(12396): topolino
02-22 19:25:39.945: V/2(12396): minni
02-22 19:25:39.945: V/3(12396): paperino
Praticamente, l'errore viene intercettato e viene lasciato il messaggio di avvenuta intercettazione, quindi il flusso del programma procede liberamente inserendo gli altri records nel database.