Come si controlla se esiste una tabella in un database SQLite Android?

Ho un’app per Android che deve controllare se c’è già un record nel database, e se no, elaborare alcune cose e infine inserirle, e semplicemente leggere i dati dal database se i dati esistono. Sto usando una sottoclass di SQLiteOpenHelper per creare e ottenere un’istanza riscrivibile di SQLiteDatabase, che ho pensato automaticamente si occupava di creare la tabella se non esisteva già (dal momento che il codice per farlo è in onCreate (… ) metodo).

Tuttavia, quando la tabella NON esiste ancora e il primo metodo eseguito sull’object SQLiteDatabase che ho è una chiamata a query (…), il mio logcat mostra un errore di “I / Database (26434): sqlite restituito: errore code = 1, msg = no tabella: appdata “, e abbastanza sicuro, la tabella appdata non viene creata.

Qualche idea sul perché?

Sto cercando un metodo per verificare se la tabella esiste (perché se non lo fa, i dati non ci sono sicuramente, e non ho bisogno di leggerlo fino a quando non scrivo, che sembra creare la tabella correttamente), o un modo per assicurarsi che venga creato, ed è solo vuoto, in tempo per quella prima chiamata a query (…)

MODIFICARE
Questo è stato pubblicato dopo le due risposte qui sotto:
Penso di aver trovato il problema. Per qualche ragione ho deciso di creare un diverso SQLiteOpenHelper per ogni tabella, anche se entrambi accedono allo stesso file di database. Penso che refactoring quel codice per utilizzare solo un OpenHelper, e la creazione di entrambe le tabelle all’interno del suo onCreate potrebbe funzionare meglio …

Prova questo:

public boolean isTableExists(String tableName, boolean openDb) { if(openDb) { if(mDatabase == null || !mDatabase.isOpen()) { mDatabase = getReadableDatabase(); } if(!mDatabase.isReadOnly()) { mDatabase.close(); mDatabase = getReadableDatabase(); } } Cursor cursor = mDatabase.rawQuery("select DISTINCT tbl_name from sqlite_master where tbl_name = '"+tableName+"'", null); if(cursor!=null) { if(cursor.getCount()>0) { cursor.close(); return true; } cursor.close(); } return false; } 

Non so nulla dell’API Android SQLite, ma se sei in grado di parlarne direttamente in SQL, puoi farlo:

 create table if not exists mytable (col1 type, col2 type); 

Questo garantirà che la tabella sia sempre creata e non genera errori se già esisteva.

Sebbene ci siano già molte buone risposte a questa domanda, mi è venuta in mente un’altra soluzione che ritengo sia più semplice. Circonda la query con un blocco try e il seguente catch:

 catch (SQLiteException e){ if (e.getMessage().contains("no such table")){ Log.e(TAG, "Creating table " + TABLE_NAME + "because it doesn't exist!" ); // create table // re-run query, etc. } } 

Ha funzionato per me!

Questo è quello che ho fatto:

 /* open database, if doesn't exist, create it */ SQLiteDatabase mDatabase = openOrCreateDatabase("exampleDb.db", SQLiteDatabase.CREATE_IF_NECESSARY,null); Cursor c = null; boolean tableExists = false; /* get cursor on it */ try { c = mDatabase.query("tbl_example", null, null, null, null, null, null); tableExists = true; } catch (Exception e) { /* fail */ Log.d(TAG, tblNameIn+" doesn't exist :((("); } return tableExists; 

Sì, risulta che la teoria nella mia modifica era corretta: il problema che causava il mancato funzionamento del metodo onCreate era il fatto che SQLiteOpenHelper oggetti SQLiteOpenHelper dovrebbero fare riferimento ai database e non avere uno separato per ogni tabella. L’imballaggio di entrambe le tabelle in un solo SQLiteOpenHelper risolto il problema.

Hai menzionato che hai creato una class che estende SQLiteOpenHelper e implementato il metodo onCreate . Stai facendo in modo che stai eseguendo tutto il tuo database acquisendo chiamate con quella class? Dovresti ricevere SQLiteDatabase oggetti SQLiteDatabase tramite SQLiteOpenHelper#getWritableDatabase e getReadableDatabase altrimenti il ​​metodo onCreate non verrà chiamato quando necessario. Se lo fai già, controlla e vedi se viene chiamato il metodo SQLiteOpenHelper#onUpgrade . In tal caso, il numero di versione del database è stato modificato ad un certo punto nel tempo, ma la tabella non è mai stata creata correttamente quando ciò è accaduto.

Per inciso, puoi forzare la ricreazione del database assicurandoti che tutte le connessioni siano chiuse e chiamando Context#deleteDatabase e poi usando SQLiteOpenHelper per darti un nuovo object db.

  // @param db, readable database from SQLiteOpenHelper public boolean doesTableExist(SQLiteDatabase db, String tableName) { Cursor cursor = db.rawQuery("select DISTINCT tbl_name from sqlite_master where tbl_name = '" + tableName + "'", null); if (cursor != null) { if (cursor.getCount() > 0) { cursor.close(); return true; } cursor.close(); } return false; } 
  • sqlite mantiene la tabella sqlite_master contenente le informazioni di tutte le tabelle e gli indici nel database.
  • Quindi qui stiamo semplicemente eseguendo il comando SELECT su di esso, otterremo il cursore che ha il conteggio 1 se la tabella esiste.
  public boolean isTableExists(String tableName) { boolean isExist = false; Cursor cursor = db.rawQuery("select DISTINCT tbl_name from sqlite_master where tbl_name = '" + tableName + "'", null); if (cursor != null) { if (cursor.getCount() > 0) { isExist = true; } cursor.close(); } return isExist; } 

no such table exists: error sta arrivando perché una volta creato il database con una tabella dopo che ogni volta che si crea una tabella nello stesso database viene visualizzato questo errore.

Per risolvere questo errore è necessario creare un nuovo database e all’interno del metodo onCreate () è ansible creare più tabelle nello stesso database.

….. Toast t = Toast.makeText (context, “try …”, Toast.LENGTH_SHORT); t.show ();

  Cursor callInitCheck = db.rawQuery("select count(*) from call", null); Toast t2a = Toast.makeText(context, "count rows " + callInitCheck.getCount() , Toast.LENGTH_SHORT); t2a.show(); callInitCheck.moveToNext(); if( Integer.parseInt( callInitCheck.getString(0)) == 0) // if no rows then do { // if empty then insert into call 

…..