Ich habe meine Tabellen in meinem erstellt, SQLiteOpenHelper
onCreate()
aber erhalten
SQLiteException: no such table
oder
SQLiteException: no such column
Fehler. Warum?
HINWEIS:
(Dies ist die zusammengeführte Zusammenfassung von zehn ähnlichen Fragen pro Woche. Es wird versucht, hier eine "kanonische" Community-Wiki-Frage / Antwort bereitzustellen, damit all diese Fragen an eine gute Referenz weitergeleitet werden können.)
Antworten:
SQLiteOpenHelper
onCreate()
undonUpgrade()
Rückrufe werden aufgerufen, wenn die Datenbank tatsächlich geöffnet wird, beispielsweise durch einen Aufruf vongetWritableDatabase()
. Die Datenbank wird nicht geöffnet, wenn das Datenbank-Hilfsobjekt selbst erstellt wird.SQLiteOpenHelper
Versionen der Datenbankdateien. Die Versionsnummer ist dasint
an den Konstruktor übergebene Argument . In der Datenbankdatei wird die Versionsnummer in gespeichertPRAGMA user_version
.onCreate()
wird nur ausgeführt, wenn die Datenbankdatei nicht vorhanden war und gerade erstellt wurde. BeionCreate()
erfolgreicher Rückgabe (keine Ausnahme) wird davon ausgegangen, dass die Datenbank mit der angeforderten Versionsnummer erstellt wurde. Als Implikation sollten SieSQLException
s nicht in sichonCreate()
selbst fangen .onUpgrade()
wird nur aufgerufen, wenn die Datenbankdatei vorhanden ist, die gespeicherte Versionsnummer jedoch niedriger ist als im Konstruktor angefordert. DasonUpgrade()
sollte das Tabellenschema auf die angeforderte Version aktualisieren.Wenn Sie das Tabellenschema in code (
onCreate()
) ändern , sollten Sie sicherstellen, dass die Datenbank aktualisiert wird. Zwei Hauptansätze:Löschen Sie die alte Datenbankdatei, damit
onCreate()
sie erneut ausgeführt wird. Dies wird häufig zur Entwicklungszeit bevorzugt, wenn Sie die Kontrolle über die installierten Versionen haben 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
die Shell.Anwendungsdaten löschen. Verwenden Sie den Anwendungsmanager.
Inkrementieren Sie die Datenbankversion, damit sie
onUpgrade()
aufgerufen wird. Dies ist etwas komplizierter, da mehr Code benötigt wird.Bei Upgrades des Entwicklungszeitschemas, bei denen Datenverlust kein Problem darstellt, können Sie einfach
execSQL("DROP TABLE IF EXISTS <tablename>")
Ihre vorhandenen Tabellen entfernen undonCreate()
die Datenbank neu aufrufen .Für freigegebene Versionen sollten Sie die Datenmigration in implementieren
onUpgrade()
damit Ihre Benutzer ihre Daten nicht verlieren.quelle
onUpdate()
Überprüfen Sie in jede alte Version und führen Sie eine ordnungsgemäße Datenmigration durch. Und dann, wenn ein Benutzer seine App aktualisiert (er hat alte Datenbankdateien),onUpgrade
wird ausgelöst, und wenn der Benutzer neu installiert wird,onCreate()
wird ausgelöst.Um hier fehlende Punkte weiter hinzuzufügen, gemäß der Anfrage von Jaskey
Die Datenbankversion wird in der
SQLite
Datenbankdatei gespeichert.catch ist der Konstruktor
Wenn der Datenbank-
name
Hilfskonstruktor mit einem (2. Parameter) aufgerufen wird, prüft die Plattform, ob die Datenbank vorhanden ist oder nicht, und ob die Datenbank vorhanden ist, ruft die Versionsinformationen aus dem Datenbankdateikopf ab und löst den richtigen Rückruf ausWie bereits in der älteren Antwort erläutert, wird die Datenbank mit dem Namen ausgelöst, wenn sie nicht vorhanden ist
onCreate
.Die folgende Erklärung erläutert den
onUpgrade
Fall anhand eines Beispiels.Angenommen, Ihre erste Version der Anwendung hatte die
DatabaseHelper
(erweiterteSQLiteOpenHelper
) Version, bei der der Konstruktor übergeben wurde,1
und dann haben Sie eine aktualisierte Anwendung mit dem neuen Quellcode bereitgestellt, dessen Version als Plattform übergeben wurde2
, und dann automatisch, wenn dieDatabaseHelper
Plattform ausgelöst wirdonUpgrade
indem die Datei bereits vorhanden ist. Die Version ist jedoch niedriger als die aktuelle Version, die Sie übergeben haben.Angenommen, Sie planen, eine dritte Version der Anwendung mit der
3
Datenbankversion as anzugeben (die Datenbankversion wird nur erhöht, wenn das Datenbankschema geändert werden soll). Bei solchen inkrementellen Upgrades müssen Sie die Upgrade-Logik von jeder Version inkrementell schreiben, um einen besser wartbaren Code zu erhaltenBeispiel Pseudocode unten:
Beachten Sie die fehlende
break
Aussage in case1
und2
. Das meine ich mit inkrementellem Upgrade.Angenommen, die alte Version ist
2
und die neue Version ist4
, dann aktualisiert die Logik die Datenbank von2
bis3
und dann bis4
Wenn die alte Version
3
und die neue Version ist4
, wird nur die Upgrade-Logik für3
to ausgeführt4
quelle
onCreate()
Wenn wir die Datenbank zum ersten Mal erstellen (dh die Datenbank ist nicht vorhanden),
onCreate()
erstellen Sie eine Datenbank mit der übergebenen VersionSQLiteOpenHelper(Context context, String name, SQLiteDatabase.CursorFactory factory, int version)
onCreate()
Die Methode erstellt die von Ihnen definierten Tabellen und führt jeden anderen von Ihnen geschriebenen Code aus. 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
onCreate()
ausführen möchten , müssen Sie adb verwenden, um die SQLite-Datenbankdatei zu löschen.onUpgrade()
SQLiteOpenHelper
sollte den Super-Konstruktor aufrufen.onUpgrade()
Methode wird nur aufgerufen, wenn die Versions-Ganzzahl größer ist als die aktuelle Version, die in der App ausgeführt wird.onUpgrade()
Methode aufgerufen werden soll, müssen Sie die Versionsnummer in Ihrem Code erhöhen.quelle
Vielleicht bin ich zu spät, aber ich möchte meine kurze und süße Antwort teilen. Bitte überprüfen Sie die Antwort auf das gleiche Problem. Es wird dir definitiv helfen. Keine tieferen Spezifikationen mehr.
Wenn Sie sich hinsichtlich der Syntax zum Erstellen einer Tabelle sicher sind, kann dies passieren, wenn Sie eine neue Spalte in derselben Tabelle hinzufügen.
1) Deinstallieren Sie von Ihrem Gerät und führen Sie es erneut aus.
ODER
2) Einstellung -> App -> ClearData
ODER
3) Ändern Sie
DATABASE_VERSION
Ihre "DatabaseHandler" -Klasse (Wenn Sie eine neue Spalte hinzugefügt haben, wird diese automatisch aktualisiert)ODER
4) Änderung
DATABASE_NAME
in Ihrer "DatabaseHandler" -Klasse (Ich hatte das gleiche Problem. Aber es gelingt mir, wenn ich mich ändereDATABASE_NAME
.)quelle
Punkte, die Sie beim Erweitern beachten sollten
SQLiteOpenHelper
super(context, DBName, null, DBversion);
- Dies sollte in der ersten Zeile des Konstruktors aufgerufen werdenonCreate
undonUpgrade
(falls erforderlich)onCreate
wird nur aufgerufen, wenngetWritableDatabase()
odergetReadableDatabase()
ausgeführt wird. Und dies wird nur einmal aufgerufen, wenn eineDBName
im ersten Schritt angegebene nicht verfügbar ist. Sie können dieonCreate
Methode create table query on method hinzufügenDBversion
einfach die Abfragen in deronUpgrade
Tabelle oder deinstallieren Sie sie einfach und installieren Sie die App.quelle
onCreate wird zum ersten Mal aufgerufen, wenn die Erstellung von Tabellen erforderlich ist. Wir müssen diese Methode überschreiben, indem wir das Skript für die Tabellenerstellung schreiben, das von SQLiteDatabase ausgeführt wird. execSQL-Methode. Nach der Ausführung in der ersten 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 wurde die Datenbankstruktur geändert, z. B. durch Hinzufügen einer zusätzlichen Spalte in der Tabelle. Angenommen, die Datenbankversion ist jetzt 2.
quelle
Sie können Datenbank & Tabelle wie erstellen
Hinweis: Wenn Sie eine andere Tabelle erstellen oder Spalten hinzufügen möchten oder keine solche Tabelle, erhöhen Sie einfach die VERSION
quelle
Die SQLite-Datenbank überschreibt zwei Methoden
1) onCreate (): Diese Methode wird nur einmal aufgerufen, wenn die Anwendung zum ersten Mal gestartet wird. Also hat es nur einmal angerufen
2) onUpgrade () Diese Methode wird aufgerufen, wenn wir die Datenbankversion ändern. Dann wird diese Methode aufgerufen. Sie wird zum Ändern der Tabellenstruktur verwendet, z. B. zum Hinzufügen einer neuen Spalte nach dem Erstellen des DB-Schemas
quelle
Eine solche gefundene Tabelle wird hauptsächlich dann nicht gefunden, wenn Sie die
SQLiteOpenHelper
Klasse nicht mit geöffnet habengetwritabledata()
und zuvor auch den make-Konstruktor mit Datenbankname & Version aufrufen müssen. UndOnUpgrade
wird immer dann aufgerufen, wenn die in derSQLiteOpenHelper
Klasse angegebene Versionsnummer einen Upgrade-Wert enthält .Unten ist das Code-Snippet (Keine solche Spalte wurde möglicherweise aufgrund eines Buchstabens im Spaltennamen gefunden):
quelle
Wenn Sie vergessen, dem Konstruktor eine "Name" -String als zweites Argument anzugeben, wird eine "In-Memory" -Datenbank erstellt, die beim Schließen der App gelöscht wird.
quelle
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.)
quelle
Ihr Datenbankname muss mit .db enden. Außerdem müssen Ihre Abfragezeichenfolgen einen Terminator (;) haben.
quelle
Überprüfen Sie Ihre Abfrage erneut in Ihrer DatabaseHandler / DatabaseManager-Klasse (je nachdem, welche Sie genommen haben).
quelle
In meinem Fall bekomme ich Artikel aus der XML-Datei mit
<string-array>
, in der ich<item>
s speichere . In diesen<item>
s halte ich SQL-Strings und wende sie einzeln mit andatabaseBuilder.addMigrations(migration)
. Ich habe einen Fehler gemacht, vergessen,\
vor dem Zitat hinzuzufügen und bekam die Ausnahme:android.database.sqlite.SQLiteException: keine solche Spalte: some_value (Code 1 SQLITE_ERROR): beim Kompilieren: INSERT INTO table_name (id, name) VALUES (1, some_value)
Das ist also eine richtige Variante:
quelle
Bei der Methode von Sqliteopenhelper werden Methoden erstellt und aktualisiert. Create wird verwendet, wenn eine Tabelle zum ersten Mal erstellt wird, und die Upgrade-Methode wird jedes Mal aufgerufen, wenn die Spaltennummer der Tabelle geändert wird.
quelle