Ich habe meine Tabellen in meiner SQLiteOpenHelper
onCreate()
erstellt, aber erhalten
SQLiteException: no such table
oder
SQLiteException: no such column
fehler. Warum?
HINWEIS:
(Dies ist die Zusammenfassung von Dutzenden ähnlicher Fragen jede Woche. Versuch, hier eine "kanonische" Community-Wiki-Frage/Antwort bereitzustellen, damit alle diese Fragen auf eine gute Referenz verwiesen werden können.)
SQLiteOpenHelper
onCreate()
und onUpgrade()
callbacks werden aufgerufen, wenn die Datenbank tatsächlich geöffnet wird, beispielsweise durch einen Aufruf an getWritableDatabase()
. Die Datenbank wird nicht geöffnet, wenn das Datenbank-Hilfsobjekt selbst erstellt wird.
SQLiteOpenHelper
gibt die Datenbankdateien aus. Die Versionsnummer ist das Argument int
, das an den Konstruktor übergeben wird. In der Datenbankdatei ist die Versionsnummer in PRAGMA user_version
gespeichert.
onCreate()
wird nur ausgeführt, wenn die Datenbankdatei nicht vorhanden war und gerade erstellt wurde. Wenn onCreate()
erfolgreich zurückgegeben wird (keine Ausnahme ausgelöst wird), wird davon ausgegangen, dass die Datenbank mit der angeforderten Versionsnummer erstellt wurde. Als Folge davon sollten Sie SQLException
s in onCreate()
nicht selbst einfangen.
onUpgrade()
wird nur aufgerufen, wenn die Datenbankdatei vorhanden ist, die gespeicherte Versionsnummer jedoch niedriger ist als im Konstruktor angefordert. onUpgrade()
sollte das Tabellenschema auf die angeforderte Version aktualisieren.
Wenn Sie das Tabellenschema im Code (onCreate()
) ändern, sollten Sie sicherstellen, dass die Datenbank aktualisiert wird. Zwei Hauptansätze:
Löschen Sie die alte Datenbankdatei, damit onCreate()
erneut ausgeführt wird. Dies wird häufig zur Entwicklungszeit bevorzugt, wenn Sie die installierten Versionen selbst kontrollieren können und Datenverlust kein Problem darstellt. Einige Möglichkeiten zum Löschen der Datenbankdatei:
Deinstallieren Sie die Anwendung. Verwenden Sie den Anwendungsmanager oder adb uninstall your.package.name
von Shell.
Anwendungsdaten löschen Verwenden Sie den Anwendungsmanager.
Inkrementieren Sie die Datenbankversion, sodass onUpgrade()
aufgerufen wird. Dies ist etwas komplizierter, da mehr Code benötigt wird.
Bei Aktualisierungen des Entwicklungszeitschemas, bei denen Datenverlust kein Problem darstellt, können Sie einfach mit execSQL("DROP TABLE IF EXISTS <tablename>")
in Ihre vorhandenen Tabellen entfernen und onCreate()
aufrufen, um die Datenbank neu zu erstellen.
Bei freigegebenen Versionen sollten Sie die Datenmigration in onUpgrade()
implementieren, damit Ihre Benutzer ihre Daten nicht verlieren.
Um hier weiter fehlende Punkte hinzuzufügen, wie auf Anfrage von Jaskey
Die Datenbankversion wird in der Datenbankdatei SQLite
gespeichert.
catch ist der Konstruktor
SQLiteOpenHelper(Context context, String name, SQLiteDatabase.CursorFactory factory, int version)
Wenn also der Datenbank-Hilfskonstruktor mit einer name
(2nd param) aufgerufen wird, prüft die Plattform, ob die Datenbank vorhanden ist oder nicht. Wenn die Datenbank vorhanden ist, ruft sie die Versionsinformationen aus dem Kopf der Datenbankdatei ab und löst den richtigen Rückruf aus
Wie bereits in der älteren Antwort erläutert, löst die Datenbank mit dem Namen onCreate
aus.
Nachfolgend wird der Fall onUpgrade
anhand eines Beispiels erläutert.
Angenommen, Ihre erste Version der Anwendung hatte DatabaseHelper
(Erweiterung SQLiteOpenHelper
), wobei die Version des Konstruktors als 1
übergeben wurde, und Sie haben dann eine aktualisierte Anwendung mit dem neuen Quellcode bereitgestellt, deren Version als 2
übergeben wurde. Dann löst die Plattform automatisch DatabaseHelper
aus, wenn die onUpgrade
erstellt wird Die Datei ist bereits vorhanden, aber die Version ist niedriger als die aktuelle Version, die Sie übergeben haben.
Angenommen, Sie planen, eine dritte Version der Anwendung mit der Datenbankversion als 3
anzugeben (die Datenbankversion wird nur erhöht, wenn das Datenbankschema geändert werden soll). Bei solchen inkrementellen Aktualisierungen müssen Sie die Aktualisierungslogik für jede Version inkrementell schreiben, um einen besser wartbaren Code zu erhalten
Beispiel Pseudo-Code unten:
@Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
switch(oldVersion) {
case 1:
//upgrade logic from version 1 to 2
case 2:
//upgrade logic from version 2 to 3
case 3:
//upgrade logic from version 3 to 4
break;
default:
throw new IllegalStateException(
"onUpgrade() with unknown oldVersion " + oldVersion);
}
}
Beachten Sie die fehlende break
-Anweisung für den Fall 1
und 2
. Das meine ich mit inkrementellem Upgrade.
Sagen Sie, wenn die alte Version 2
und die neue Version 4
ist, aktualisiert die Logik die Datenbank von 2
auf 3
und dann auf 4
.
Wenn die alte Version 3
und die neue Version 4
ist, wird nur die Aktualisierungslogik für 3
auf 4
ausgeführt.
onCreate()
Beim ersten Erstellen einer Datenbank (d. H. Datenbank ist nicht vorhanden) onCreate()
Datenbank mit Version erstellen, die übergeben wird SQLiteOpenHelper(Context context, String name, SQLiteDatabase.CursorFactory factory, int version)
onCreate()
erstellt die Tabellen, die Sie definiert haben, und führt jeden anderen Code aus, den Sie geschrieben haben. Diese Methode wird jedoch nur aufgerufen, wenn die SQLite-Datei im Datenverzeichnis Ihrer App fehlt (/data/data/your.apps.classpath/databases
).
Diese Methode wird nicht aufgerufen, wenn Sie Ihren Code geändert und im Emulator neu gestartet haben. Wenn Sie möchten, dass onCreate()
ausgeführt wird, müssen Sie die SQLite-Datenbankdatei mit adb löschen.
onUpgrade()
SQLiteOpenHelper
sollte den Superkonstruktor aufrufen.onUpgrade()
wird nur aufgerufen, wenn die Versionsganzzahl größer ist als die aktuelle Version, die in der App ausgeführt wird.onUpgrade()
aufgerufen wird, müssen Sie die Versionsnummer in Ihrem Code erhöhen.Vielleicht bin ich zu spät, aber ich möchte meine kurze und süße Antwort mit Ihnen teilen. Bitte überprüfen Sie Answer für dasselbe Problem. Es wird dir definitiv helfen. Keine tiefen Spezifikationen mehr.
Wenn Sie mit der Syntax zum Erstellen von Tabellen vertraut sind, kann dies passieren, wenn Sie in derselben Tabelle eine neue Spalte hinzufügen.
1) Deinstalliere dein Gerät und führe es erneut aus.
OR
2) Einstellung -> App -> ClearData
OR
3) Ändern Sie DATABASE_VERSION
in Ihrer "DatabaseHandler" -Klasse (Wenn Sie eine neue Spalte hinzugefügt haben, wird das Upgrade automatisch durchgeführt)
public DatabaseHandler(Context context) {
super(context, DATABASE_NAME, null, DATABASE_VERSION);
}
OR
4) Change DATABASE_NAME
in Ihrer "DatabaseHandler" -Klasse (Ich hatte das gleiche Problem. Aber ich ändere DATABASE_NAME
.)
Punkte, die bei der Erweiterung von SQLiteOpenHelper
zu beachten sind
super(context, DBName, null, DBversion);
- Dies sollte in der ersten Zeile des Konstruktors aufgerufen werdenonCreate
und onUpgrade
(falls erforderlich)onCreate
wird nur aufgerufen, wenn getWritableDatabase()
oder getReadableDatabase()
ausgeführt wird. Dies wird nur einmal aufgerufen, wenn eine im ersten Schritt angegebene DBName
nicht verfügbar ist. Sie können eine Tabellenabfrage für die onCreate
-Methode hinzufügenDBversion
und führen Sie die Abfragen in der Tabelle onUpgrade
durch.onCreate wird zum ersten Mal aufgerufen, wenn Tabellen erstellt werden müssen. Wir müssen diese Methode überschreiben, in der wir das Skript zur Tabellenerstellung schreiben, das von SQLiteDatabase ausgeführt wird. execSQL-Methode. Nach der erstmaligen Bereitstellung wird diese Methode nicht mehr aufgerufen.
onUpgrade Diese Methode wird aufgerufen, wenn die Datenbankversion aktualisiert wird. Angenommen, bei der ersten Bereitstellung war die Datenbankversion 1, und bei der zweiten Bereitstellung gab es Änderungen in der Datenbankstruktur, z. Angenommen, die Datenbankversion ist jetzt 2.
Sie können Datenbank & Tabelle erstellen
public class DbHelper extends SQLiteOpenHelper {
private static final String DBNAME = "testdatbase.db";
private static final int VERSION = 1;
public DbHelper(Context context) {
super(context, DBNAME, null, VERSION);
// TODO Auto-generated constructor stub
}
@Override
public void onCreate(SQLiteDatabase db) {
// TODO Auto-generated method stub
db.execSQL("create table BookDb(id integer primary key autoincrement,BookName text,Author text,IssuedOn text,DueDate text,Fine text,Totalfine text");
}
@Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
db.execSQL("DROP TABLE IF EXISTS BookDb");
onCreate(db);
}
}
Hinweis: Wenn Sie eine andere Tabelle erstellen oder Spalten hinzufügen oder keine solche Tabelle hinzufügen möchten, erhöhen Sie einfach die VERSION
Wenn Sie vergessen, dem Konstruktor eine Zeichenfolge "name" als zweites Argument anzugeben, wird eine Datenbank "im Arbeitsspeicher" erstellt, die beim Schließen der App gelöscht wird.
eine solche Tabelle wird nicht gefunden, wenn Sie die SQLiteOpenHelper
-Klasse nicht mit getwritabledata()
geöffnet haben und davor müssen Sie auch build-Konstruktor mit databasename & version aufrufen. Und OnUpgrade
wird aufgerufen, wenn in der Versionsnummer ein Upgrade-Wert in der SQLiteOpenHelper
-Klasse angegeben ist.
Nachfolgend finden Sie den Code-Ausschnitt (Keine der gefundenen Spalten kann aufgrund eines Buchstabens im Spaltennamen sein):
public class database_db {
entry_data endb;
String file_name="Record.db";
SQLiteDatabase sq;
public database_db(Context c)
{
endb=new entry_data(c, file_name, null, 8);
}
public database_db open()
{
sq=endb.getWritableDatabase();
return this;
}
public Cursor getdata(String table)
{
return sq.query(table, null, null, null, null, null, null);
}
public long insert_data(String table,ContentValues value)
{
return sq.insert(table, null, value);
}
public void close()
{
sq.close();
}
public void delete(String table)
{
sq.delete(table,null,null);
}
}
class entry_data extends SQLiteOpenHelper
{
public entry_data(Context context, String name, SQLiteDatabase.CursorFactory factory,
int version) {
super(context, name, factory, version);
// TODO Auto-generated constructor stub
}
@Override
public void onCreate(SQLiteDatabase sqdb) {
// TODO Auto-generated method stub
sqdb.execSQL("CREATE TABLE IF NOT EXISTS 'YOUR_TABLE_NAME'(Column_1 text not null,Column_2 text not null);");
}
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
onCreate(db);
}
}
Überprüfen Sie Ihre Abfrage erneut in der DatabaseHandler/DatabaseManager-Klasse (je nachdem, was Sie angenommen haben).
Deinstallieren Sie Ihre Anwendung vom Emulator oder Gerät. Führen Sie die App erneut aus. (OnCreate () wird nicht ausgeführt, wenn die Datenbank bereits vorhanden ist)
Ihr Datenbankname muss mit .db enden. Ihre Abfragezeichenfolgen müssen ein Abschlusszeichen (;) enthalten.
Die Sqlite-Datenbank überschreibt zwei Methoden
1) onCreate (): Diese Methode wurde nur einmal aufgerufen, wenn die Anwendung zum ersten Mal gestartet wird. So rief es nur einmal an
2) onUpgrade () Diese Methode wurde aufgerufen, wenn wir die Datenbankversion ändern. Dann werden diese Methoden aufgerufen. Sie wird für die Änderung der Tabellenstruktur verwendet