Ich fange mit SQLite und Datenbanken in Android an und habe gerade dieses Problem gefunden. Ich habe viele ähnliche Fragen gelesen, aber noch keine Lösung gefunden.
Dies ist der Fehler, den ich bekomme:
E/Android-Laufzeit (529): Ursache: Android.database.sqlite.SQLiteException: keine solche Tabelle: ligas_bd:, beim Kompilieren: SELECT * FROM ligas_bd
Das ist mein 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) { }
Ich habe auch mein Telefon mit dem Root-Explorer "data/data/mypackagename/database" eingecheckt und die Datenbank erscheint dort als normal.
Meine Datenbank und die Haupttabelle haben denselben Namen, wie Sie auf diesem Bild des SQLite-Datenbankbrowsers sehen können:
Ich erstelle die Tabelle nicht, ich habe sie vor der Verwendung von SQLite Database Browser erstellt und versuche nur, daraus zu lesen
Ich weiß nicht wie, aber ich habe es endlich behoben. Ich habe gerade wieder angefangen, diesmal nach diesem Tutorial . Ich hoffe es hilft!
Dies ist nur eine Vermutung, aber ich kann sehen, dass hier drei mögliche Dinge passieren ...
this.getReadableDatabase()
in Ihrer createDatabase()
-Methode wird automatisch eine leere Datenbank erstellt.assets
-Ordner zu kopieren, schlägt fehl oder die Datenbank wird an die falsche Stelle kopiert.db.rawQuery(...)
aus Ihrem Hauptcode aufrufen.Um es weiter zu erklären, ist es nützlich, die Quelle für SQLiteOpenHelper zu betrachten.
Wenn Sie eine Instanz von SQLiteOpenHelper
erstellen, werden Werte wie Datenbankname und -version festgelegt, die Datenbank wird jedoch nicht erstellt. Stattdessen prüft der erste Aufruf von getReadableDatabase()
oder getWritableDatabase()
, ob die Datenbank vorhanden ist, und erstellt sie nicht, falls nicht. Nach dem Erstellen der leeren Datenbank wird die onCreate(...)
-Methode aufgerufen, die in Ihrem Fall nichts tut.
Zu Punkt 2 (oben) - Sie sagen, dass DB_PATH
/data/data/mypackagename/databases
ist. Wenn das wirklich der Fall ist und Sie keine /
-Nachfolge haben, dann ist die Zeile ...
String myPath = DB_PATH + DB_NAME;
... setzt myPath
auf /data/data/mypackagename/databasesligas_db
. Selbst wenn die Kopie von assets
erfolgreich ist, befindet sich die kopierte Datenbank in dem Fall nicht dort, wo sie erwartet wird.
Schließlich wird bei Punkt 3 (oben) beim Aufruf von db.rawQuery(...)
die Instanz, auf die db
zeigt, vom vorherigen Aufruf an getWritableDatabase()
zurückgegeben. Angenommen, die Kopie von assets
ist fehlgeschlagen oder wurde in den falschen Pfad kopiert, zeigt db
auf die leere Datenbank, die in Schritt 1 erstellt wurde.
Der Fehler, den Sie erhalten, ist, dass die Tabelle nicht vorhanden ist und kein Fehler ist, der darauf hinweist, dass die Datenbank nicht vorhanden ist. Die einzige logische Erklärung ist, dass sie eine Abfrage für eine leere Datenbank ausführt und nicht für die Datenbank, aus der kopiert wurde assets
.
EDIT: Eine andere Sache, die ich erwähnen wollte. Es ist keine gute Idee, hartcodierte Pfade zu einem der Android-Verzeichnisse zu verwenden. Zum Beispiel - obwohl auf den meisten Geräten /data/data/<package-name>/databases
das Verzeichnis ist, in dem Datenbanken erstellt werden, ist dies keine Garantie. Es ist viel sicherer, wenn Sie die getDatabasePath(...)
-Methode aufrufen, da ein File
-Objekt zurückgegeben wird, mit dem der Pfad zum Datenbankverzeichnis abgerufen werden kann, das von den Android-Datenbankklassen verwendet wird.
Ich hatte das gleiche Problem und es wurde behoben, indem das Projekt gereinigt und die App von meinem Testgerät gelöscht und erneut installiert wurde. Ich glaube, es kam vor, weil ich ein anderes Tutorial befolgt habe, bei dem versehentlich eine leere Datenbank erstellt wurde. Der korrigierte Code ruft die alte leere Datenbank ab.
Wenn Sie Ihre App auf Ihrem Gerät ausführen, gehen Sie zu >> Einstellungen (auf Android-Gerät) >>> Anwendung >>> Suchen Sie Ihre Anwendung. Danach debuggen oder installieren Sie Ihre neue Anwendung erneut.
Ich habe dieses Problem dadurch gelöst ...
Die Ausnahme ist sehr klar, Sie haben die Datenbank (ligas_db) erstellt, aber keine Tabelle darin (keine solche Tabellenausnahme = keine Tabelle namens ligas_db)
Überprüfen Sie dies: http://www.vogella.de/articles/AndroidSQLite/article.html
(¿Eres Antonio Recio? Jaja)
Ich hatte das gleiche Problem, die Dateinamenerweiterung .db in den Dateinamen aufzunehmen:
private static String DB_NAME = "ligas_bd.db";
Sie haben ligas_bd
als Namen der Datenbank und versuchen, SELECT
von ihr auszuprobieren.
Mein Problem war, dass ich "/ database /" am Ende meines Pfadnamens gelassen habe. Was für mich so verwirrend war, ist der Code, der zuvor beim Laden einer dbconnection als Instanzvariable gespeichert wurde. Als ich dann die Methoden getReadableDatabase () und getWritableDatabase () verwenden musste, zog man die leere Datenbank, die im "echten" Datenbankpfad erstellt wurde.
INCORRECT/data/data/mypackagename/
CORRECT/data/data/mypackagename/databases/
+1 an @Squonk, dessen Antwort mir letztendlich geholfen hat, das aufzuspüren!
Sie müssen zuerst eine Tabelle erstellen, bevor Sie eine Auswahl treffen. Möglicherweise haben Sie das zuvor erstellt, müssen es jedoch nach dem Öffnen der Datenbankverbindung erstellen.