web-dev-qa-db-fra.com

Android SQLite "pas de table" exception

Je commence à utiliser SQLite et les bases de données sous Android et je viens de trouver ce problème. J'ai lu beaucoup de questions similaires mais je n'ai pas encore trouvé de solution.

C'est l'erreur que j'obtiens:

E/AndroidRuntime (529): Causé par: Android.database.sqlite.SQLiteException: aucune table de ce type: ligas_bd:, pendant la compilation: SELECT * FROM ligas_bd

Ceci est mon code. 

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) { }

J'ai également enregistré dans mon téléphone avec root Explorer data/data/mypackagename/database et la base de données y apparaît normalement.

Ma base de données et la table principale ont le même nom, comme vous pouvez le voir sur cette image du navigateur de base de données SQLite:

screen capture

Je ne crée pas la table, je l'ai créée avant d'utiliser SQLite Database Browser et j'essaie simplement de la lire.


Je ne sais pas comment, mais j'ai finalement résolu le problème. Je viens de recommencer, cette fois-ci en suivant ce tutoriel . J'espère que ça aide!

20
andoni90

Ce n'est qu'une hypothèse, mais je peux voir trois choses possibles qui se passent ici ...

  1. L'appel de this.getReadableDatabase() dans votre méthode createDatabase() crée automatiquement une base de données vide.
  2. Votre tentative de copie de votre base de données pré-créée à partir de votre dossier assets échoue ou la base de données est en cours de copie au mauvais endroit.
  3. La base de données vide créée à l'étape 1 (ci-dessus) est celle qui est interrogée lorsque vous appelez db.rawQuery(...) à partir de votre code principal.

Pour expliquer davantage, il est utile de regarder le source de SQLiteOpenHelper

Lorsque vous créez une instance de SQLiteOpenHelper, il définit des éléments tels que le nom et la version de la base de données, mais ne crée pas la base de données. Au lieu de cela, le premier appel à getReadableDatabase() ou à getWritableDatabase() vérifie si la base de données existe et si elle ne l’a pas créée. Après avoir créé la base de données vide, la méthode onCreate(...) est appelée, ce qui, dans votre cas, ne fait rien.

Au point 2 (ci-dessus) - vous dites que DB_PATH est /data/data/mypackagename/databases. Si c'est vraiment le cas et que vous n'avez pas de / final, la ligne ...

String myPath = DB_PATH + DB_NAME;

... va définir myPath à /data/data/mypackagename/databasesligas_db. Dans ce cas, même si la copie de assets réussit, la base de données copiée ne sera pas celle que vous attendez.

Enfin, au point 3 (ci-dessus), lorsque vous appelez db.rawQuery(...), l'instance sur laquelle pointe db est renvoyée par l'appel précédent à getWritableDatabase(). En supposant que la copie de assets a échoué ou qu'elle ait été copiée dans un chemin incorrect, db pointe sur la base de données vide créée à l'étape 1.

L'erreur que vous obtenez est que la table n'existe pas et qu'il ne s'agit pas d'une erreur indiquant que la base de données n'existe pas. La seule explication logique est qu'il exécute une requête sur une base de données vide et non sur celle copiée. assets.

EDIT: Une autre chose que je voulais mentionner. Ce n'est pas une bonne idée d'utiliser des chemins codés en dur vers l'un des répertoires Android. Par exemple, bien que sur la plupart des périphériques, le répertoire dans lequel les bases de données sont créées sera /data/data/<package-name>/databases, ce n’est pas une garantie. Il est beaucoup plus sûr d’appeler la méthode getDatabasePath(...) car elle renverra un objet File pouvant être utilisé pour obtenir le chemin du répertoire de la base de données utilisé par les classes de base de données Android.

19
Squonk

J'ai eu le même problème et je l'ai corrigé en nettoyant le projet, en supprimant l'application de mon périphérique de test, puis en le réinstallant. Je crois que cela s’est produit parce que j’ai suivi un autre tutoriel qui a créé une base de données vide par erreur. Le code corrigé récupérait l'ancienne base de données vide. 

17
Logan

Si vous exécutez votre application sur votre appareil, allez à >> Paramètres (dans l'appareil Android) >>> application >>> localisez votre application >> effacer les données et le cache. Après cela, déboguez ou réinstallez votre nouvelle application. 

J'ai résolu ce problème en faisant cela ...

12
Firhat

L'exception est très claire, vous avez créé la base de données (ligas_db) mais pas une table à l'intérieur (pas d'exception de table = il n'y a pas de table nommée ligas_db)

Vérifiez ceci: http://www.vogella.de/articles/AndroidSQLite/article.html

(¿Eres Antonio Recio? Jaja)

1
Enrique Marcos

J'ai eu le même problème, essayez d'inclure l'extension .db dans le nom du fichier comme:

private static String DB_NAME = "ligas_bd.db";
0
Uğur Dinç

Vous avez ligas_bd comme nom de la base de données et vous essayez de la remplacer par SELECT.

0
Abhishek Chanda

Mon problème était que je laissais "/ database /" à la fin de mon nom de chemin. Ce qui était tellement déroutant pour moi, c’est le code qui fonctionnait auparavant lorsque je chargeais un connecteur de base de données et le stockais en tant que variable d’instance. Ensuite, lorsque j'ai eu besoin d'utiliser les méthodes getReadableDatabase () et getWritableDatabase (), ils ont continué à extraire la base de données vide créée dans le chemin "réel" des bases de données.

INCORRECT/data/data/mypackagename/

CORRECT/data/data/mypackagename/databases/

+1 à @Squonk qui a répondu m'a finalement aidé à localiser cela!

0
bgolson

Vous devez d'abord créer une table avant de la sélectionner. Vous avez peut-être déjà créé, mais vous devez le créer après avoir ouvert la connexion à la base de données. 

0
Dhruvisha