Tengo una aplicación de Android que debe verificar si ya hay un registro en la base de datos, y si no, procesar algunas cosas y eventualmente insertarlo, y simplemente leer los datos de la base de datos si los datos existen. Estoy usando una subclase de SQLiteOpenHelper para crear y obtener una instancia regrabable de SQLiteDatabase, que pensé que automáticamente se encargaba de crear la tabla si aún no existía (ya que el código para hacer eso está en onCreate (... ) método).
Sin embargo, cuando la tabla NO existe todavía, y el primer método que se ejecutó en el objeto SQLiteDatabase que tengo es una llamada a la consulta (...), mi logcat muestra un error de "I / Database (26434): sqlite regresó: error code = 1, msg = no such table: appdata ", y efectivamente, la tabla appdata no se está creando.
¿Alguna idea de por qué?
Estoy buscando un método para probar si la tabla existe (porque si no existe, los datos ciertamente no están en ella, y no necesito leerlos hasta que escribo en ellos, lo que parece crear la tabla correctamente), o una forma de asegurarse de que se cree, y esté simplemente vacío, a tiempo para esa primera llamada para consultar (...)
EDITAR
Esto se publicó después de las dos respuestas a continuación:
Creo que he encontrado el problema. Por alguna razón, decidí que se suponía que debía crearse un SQLiteOpenHelper diferente para cada tabla, aunque ambos acceden al mismo archivo de base de datos. Creo que refactorizar ese código para usar solo un OpenHelper y crear ambas tablas dentro de su onCreate puede funcionar mejor ...
cursor.close();
select * from sqlite_master where UPPER(name) = 'ROUTES'.
No sé nada sobre la API de SQLite de Android, pero si puede hablar con ella directamente en SQL, puede hacer esto:
create table if not exists mytable (col1 type, col2 type);
Lo que garantizará que la tabla siempre se cree y no arroje ningún error si ya existía.
fuente
Aunque ya hay muchas buenas respuestas a esta pregunta, se me ocurrió otra solución que creo que es más simple. Rodee su consulta con un bloque de prueba y la siguiente captura:
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. } }
¡Funcionó para mí!
fuente
e.getMessage().contains("no such table")
es peor que usar excepciones para controlar el flujo. Ambos son de mal estilo, pero analizar mensajes de error para un texto específico es incluso de muy mal estilo.Esto es lo que hice:
/* 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;
fuente
Sí, resulta que la teoría en mi edición era correcta: el problema que causaba que el método onCreate no se ejecutara era el hecho de que los
SQLiteOpenHelper
objetos deberían referirse a bases de datos y no tener una separada para cada tabla. Empaquetando ambas tablas en una seSQLiteOpenHelper
resolvió el problema.fuente
Mencionaste que has creado una clase que amplía
SQLiteOpenHelper
e implementa elonCreate
método. ¿Se está asegurando de realizar todas las llamadas de adquisición de su base de datos con esa clase? Solo debe obtenerSQLiteDatabase
objetos a través deSQLiteOpenHelper#getWritableDatabase
y, de logetReadableDatabase
contrarioonCreate
, no se llamará al método cuando sea necesario. Si ya está haciendo eso, verifique siSQLiteOpenHelper#onUpgrade
se está llamando al método en su lugar. Si es así, el número de versión de la base de datos se cambió en algún momento, pero la tabla nunca se creó correctamente cuando eso sucedió.Además, puede forzar la recreación de la base de datos asegurándose de que todas las conexiones a ella estén cerradas y llamando
Context#deleteDatabase
y luego usandoSQLiteOpenHelper
para darle un nuevo objeto db.fuente
// @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; }
fuente
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; }
fuente
no such table exists: error
viene porque una vez que crea una base de datos con una tabla después de eso, siempre que crea una tabla en la misma base de datos, aparece este error.Para solucionar este error debes tener que crear una nueva base de datos y dentro del método onCreate () puedes crear múltiples tablas en la misma base de datos.
fuente
La condición importante es SI NO EXISTE comprobar que la tabla ya existe o no está en la base de datos
me gusta...
String query = "CREATE TABLE IF NOT EXISTS " + TABLE_PLAYER_PHOTO + "(" + KEY_PLAYER_ID + " TEXT," + KEY_PLAYER_IMAGE + " TEXT)"; db.execSQL(query);
fuente
Me enfrenté a eso y lo resolví intentando capturar algo tan simple como que hago lo que quiero en la tabla, si no existe, causará un error, así que cógelo por excepciones y créalo :)
SQLiteDatabase db=this.getWritableDatabase(); try{ db.execSQL("INSERT INTO o_vacations SELECT * FROM vacations"); db.execSQL("DELETE FROM vacations"); }catch (SQLiteException e){ db.execSQL("create table o_vacations (id integer primary key ,name text ,vacation text,date text,MONTH text)"); db.execSQL("INSERT INTO o_vacations SELECT * FROM vacations"); db.execSQL("DELETE FROM vacations"); }
fuente
..... Toast t = Toast.makeText (contexto, "probar ...", 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
.....
fuente