2012-03-28 19 views
18

Estoy empezando a SQLite y bases de datos en Android y acabo de encontrar este problema. He leído muchas preguntas similares pero todavía no he encontrado una solución.Android SQLite excepción "no such table"

Este es el error que estoy recibiendo:

E/Android Runtime (529): Causado por: android.database.sqlite.SQLiteException: no hay tal tabla: ligas_bd:, durante la compilación: SELECT * FROM ligas_bd

Éste es mi código.

DBHelper myDbHelper = new DBHelper(this); 
myDbHelper = new DBHelper(this); 
try { 
    myDbHelper.createDataBase(); 
} catch (IOException ioe) { 
    throw new Error("Unable to create database"); 
} 
try { 
    myDbHelper.open(); 
    SQLiteDatabase db = null; 
    db = myDbHelper.getWritableDatabase(); 
    String[] args = new String[] {""}; 
    Cursor c = db.rawQuery(" SELECT * FROM ligas_bd", args); <---- Error in this line 
    if (c.moveToFirst()) { 
     do { 
      String cod = c.getString(0); 
      String nombre = c.getString(1); 
      String flag = c.getString(0); 
      String cod_url = c.getString(0); 
      ligas.add(new Item_Liga(nombre, flag, cod, cod_url)); 
     } while(c.moveToNext()); 
    } 
}catch(SQLException sqle){ 
    throw sqle; 
} 

DBHelper.java

public class DBHelper extends SQLiteOpenHelper{ 
private static String DB_NAME = "ligas_bd"; 
private SQLiteDatabase myDataBase; 
private final Context myContext; 

public DBHelper(Context context) { 
    super(context, DB_NAME, null, 1); 
    this.myContext = context; 
} 

public void createDataBase() throws IOException{ 
    boolean dbExist = checkDataBase(); 
    if(dbExist){ } 
    else { 
     this.getReadableDatabase(); 
     try { 
      copyDataBase(); 
     } catch (IOException e) { 
      throw new Error("Error copiando Base de Datos"); 
     } 
    } 
} 
private boolean checkDataBase(){ 
    SQLiteDatabase checkDB = null; 
    try { 
     String myPath = DB_PATH + DB_NAME; 
     checkDB = SQLiteDatabase.openDatabase(myPath, null, SQLiteDatabase.OPEN_READONLY); 
    } catch(SQLiteException e) { } 
    if(checkDB != null) { 
     checkDB.close(); 
    } 
    return checkDB != null ? true : false; 
} 

private void copyDataBase() throws IOException{ 
    InputStream myInput = myContext.getAssets().open(DB_NAME); 
    String outFileName = DB_PATH + DB_NAME; 
    OutputStream myOutput = new FileOutputStream(outFileName); 
    byte[] buffer = new byte[1024]; 
    int length; 
    while ((length = myInput.read(buffer))>0) { 
     myOutput.write(buffer, 0, length); 
    } 
    myOutput.flush(); 
    myOutput.close(); 
    myInput.close(); 
} 

public void open() throws SQLException{ 
    try { 
     createDataBase(); 
    } catch (IOException e) { 
     throw new Error("Ha sido imposible crear la Base de Datos"); 
    } 
    String myPath = DB_PATH + DB_NAME; 
    myDataBase = SQLiteDatabase.openDatabase(myPath, null, SQLiteDatabase.OPEN_READONLY); 
} 

@Override 
public synchronized void close() { 
    if(myDataBase != null) 
    myDataBase.close(); 
    super.close(); 
} 

@Override 
public void onCreate(SQLiteDatabase db) { } 

@Override 
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) { } 

También comprobé en mi teléfono con el Explorador de raíz de datos/datos/nombre_paquete/bases de datos y la base de datos aparece allí como normal.

Mi base de datos y la tabla principal tienen el mismo nombre, como se puede ver en esta foto del explorador de base de datos SQLite:

screen capture

yo no voy a crear la tabla, lo creé antes de usar la base de datos SQLite Navegador y solo estoy tratando de leerlo


No sé cómo, pero finalmente lo solucioné. Empecé de nuevo, esta vez siguiendo this tutorial. Espero que ayude!

+0

¿Qué es 'DB_PATH'? – Squonk

+0

es la ruta donde debe estar la base de datos. Es/data/data/mypackagename/databases – andoni90

Respuesta

16

Ésta es sólo una suposición, pero puedo ver tres cosas posibles están sucediendo aquí ...

  1. Calling this.getReadableDatabase() en su método de createDatabase() está creando automáticamente una base de datos vacía.
  2. Su intento de copiar su base de datos creada desde su carpeta assets está fallando o la base de datos está siendo copiada en el lugar equivocado.
  3. La base de datos vacía creada en el paso 1 (arriba) es la que se está consultando cuando llama al db.rawQuery(...) desde su código principal.

Para explicar mejor es usefult mirar la fuente de SQLiteOpenHelper

Cuando se crea una instancia de SQLiteOpenHelper que pone las cosas como el nombre y la versión de base de datos pero no crea la base de datos.En cambio, la primera llamada a getReadableDatabase() o getWritableDatabase() comprueba si la base de datos existe y si no la crea. Después de crear la base de datos vacía, se llama al método onCreate(...) que, en su caso, no hace nada.

En el punto 2 (arriba) - usted dice que DB_PATH es /data/data/mypackagename/databases. Si ese es realmente el caso y que no han arrastra / entonces la línea ...

String myPath = DB_PATH + DB_NAME; 

... establecerá myPath-/data/data/mypackagename/databasesligas_db. En ese caso, incluso si la copia de assets tiene éxito, la base de datos copiada no estará donde usted espera que esté.

Finalmente en el punto 3 (arriba) cuando se llama a la instancia que db.rawQuery(...)db puntos que es devuelto por la llamada anterior a getWritableDatabase(). Suponiendo que la copia de assets ha fallado o que se ha copiado en el camino incorrecto, db estará apuntando a la base de datos vacío creado en el paso 1.

El error que se obtiene es que la tabla no existe y ISN Es un error que indica que la base de datos no existe; la única explicación lógica es que está realizando una consulta en una base de datos vacía y no en la que se ha copiado desde assets.

EDITAR: Otra cosa que quise mencionar. No es una buena idea usar rutas codificadas a ninguno de los directorios de Android. Por ejemplo, aunque en la mayoría de los dispositivos, el directorio donde se crean las bases de datos será /data/data/<package-name>/databases, esto no es una garantía. Es mucho más seguro si llama al método getDatabasePath(...), ya que devolverá un objeto File que se puede usar para obtener la ruta al directorio de bases de datos utilizado por las clases de base de datos de Android.

+0

+1 por buena respuesta. :) – PhatHV

+1

la ruta está bien, tiene el "/" al final, así que ese no es el error. Si cambio la ruta arroja otra excepción, por lo que la ruta es correcta y está encontrando correctamente la base de datos. Es algo extraño – andoni90

+0

@koneX: en ese caso, intente llamar a 'File dbFile = getDatabasePath (" ligas_bd ")' y registrar la ruta del objeto 'dbFile' utilizando logcat o simplemente mostrarlo usando' Toast'. Haga esto inmediatamente antes de llamar 'db.rawQuery (...)' en su código principal. Esto al menos le mostrará la ruta que usa 'SQLiteOpenHelper' para acceder a la base de datos. – Squonk

1

La excepción está muy claro, que haya creado la base de datos (ligas_db) pero no una mesa dentro de ella (sin excepción tales tabla = no hay un llamado ligas_db tabla)

Comprobar esto: http://www.vogella.de/articles/AndroidSQLite/article.html

(¿Eres Antonio Recio? Jaja)

+0

El nombre de la base de datos y el nombre de la tabla son los mismos, vea la foto de arriba en la edición. Gracias (S no, no soy Antonio Recio jajajajaja) – andoni90

0

Tiene ligas_bd como el nombre de la base de datos y usted está tratando de SELECT de la misma.

+0

La base de datos y la tabla tienen el mismo nombre, ver la edición en la publicación anterior, por favor. Gracias – andoni90

0

Primero debe crear la tabla antes de seleccionarla. Puede haber creado antes pero necesita crearlo después de abrir la conexión a la base de datos.

+0

No sé a qué te refieres. Lo creé antes de usar su propio editor, y ahora tengo que crearlo en el código? ¿Y como hacer eso? – andoni90

+0

está usando esto: db = myDbHelper.getWritableDatabase(); Después de esto, escriba el código para crear la tabla si no existe. o abra la conexión de db antes de crear su declaración de tabla. – Dhruvisha

+0

Quiero obtener las tablas de un db existente que puse en la carpeta de activos, no quiero crear ninguna tabla – andoni90

15

Tuve el mismo problema y lo solucioné al limpiar el proyecto y eliminar la aplicación de mi dispositivo de prueba y volver a instalarla. Creo que ocurrió porque seguí otro tutorial que creó una base de datos vacía por error. El código corregido estaba recuperando la antigua base de datos vacía.

+0

Usted señor, se merece muchos más votos favorables de los que puedo darle. También tuve este error, y tu consejo es qué resolvió el problema. ¡¡¡¡Gracias!!!! – Salmononius2

+0

En mi caso tuve que usar un emulador completamente nuevo, pero esto es lo que también me funcionó – heLL0

+0

Probablemente sea la respuesta – Zen

0

Mi problema fue que dejé "/ databases /" al final de mi nombre de ruta. Lo que era tan confuso para mí es el código que funcionaba antes cuando cargaba una conexión de db y la almacenaba como una variable de instancia. Luego, cuando tuve que hacer uso de los métodos getReadableDatabase() y getWritableDatabase(), seguían trabajando en la base de datos vacía creada en la ruta de las bases de datos "reales".

INCORRECTO /data/data/nombre_paquete/

CORRECTO /datos/datos/nombre_paquete/bases de datos/

1 a @Squonk quién es la respuesta finalmente me ayudó a realizar el seguimiento de esto abajo!

11

Si está ejecutando su aplicación en su dispositivo, vaya a >> Configuración (en dispositivo Android) >>> aplicación >>> localice su aplicación >> borrar datos y caché. Después de eso, depurar o instalar de nuevo su nueva aplicación ..

I resuelto este problema haciendo que ...

0

que tenían el mismo problema tratar de incluir.extensión db en el nombre de archivo como:

private static String DB_NAME = "ligas_bd.db"; 
Cuestiones relacionadas