Quand SQLiteOpenHelper onCreate() / onUpgrade() est-il exécuté?
J'ai créé mes tables de ma SQLiteOpenHelper
onCreate()
mais recevoir
SQLiteException: no such table
Ou
SQLiteException: no such column
Erreurs. Pourquoi?
REMARQUE:
(Ceci est le résumé amalgamé de dizaines de questions similaires chaque semaine. Tenter de fournir une question/réponse wiki communautaire "canonique" ici afin que toutes ces questions puissent être dirigées vers une bonne référence.)
13 réponses
SQLiteOpenHelper
onCreate()
et onUpgrade()
les rappels sont invoquées lorsque la base de données est réellement ouvert, par exemple par un appel à getWritableDatabase()
. La base de données n'est pas ouverte lorsque l'objet d'assistance de base de données lui-même est créé.
SQLiteOpenHelper
versions les fichiers de base de données. Le numéro de version est l'argument int
passé au constructeur . Dans le fichier de base de données, le numéro de version est stockée dans PRAGMA user_version
.
onCreate()
est exécuté uniquement lorsque la base de données le fichier n'existait pas et vient d'être créé. Si onCreate()
retourne avec succès (ne lance pas d'exception), La base de données est supposée être créée avec le numéro de version demandé. Comme conséquence, vous ne devriez pas attraper SQLException
s onCreate()
vous-même.
onUpgrade()
est appelé uniquement lorsque le fichier de base de données existe mais que le numéro de version stocké est inférieur à celui demandé dans le constructeur. Le {[2] } doit mettre à jour le schéma de table à la version demandée.
Lors de la modification du schéma de table dans le code (onCreate()
), vous devez vous assurer que la base de données est mise à jour. Deux approches principales:
-
Supprimez l'ancien fichier de base de données afin que
onCreate()
soit à nouveau exécuté. Ceci est souvent préféré au moment du développement où vous avez le contrôle sur les versions installées et la perte de données n'est pas un problème. Quelques façons de supprimer le fichier de base de données:Désinstallez l'application. Utilisez le gestionnaire d'applications ou {[15] } du shell.
Effacer les données d'application. L'utilisation de l'application gestionnaire.
-
Incrémente la version de la base de données afin que
onUpgrade()
soit invoqué. C'est un peu plus compliqué car plus de code est nécessaire.Pour les mises à niveau de schéma en temps de développement où la perte de données n'est pas un problème, vous pouvez simplement utiliser
execSQL("DROP TABLE IF EXISTS <tablename>")
in pour supprimer vos tables existantes et appeleronCreate()
pour recréer la base de données.Pour les versions publiées, vous devez implémenter la migration des données dans
onUpgrade()
afin que vos utilisateurs ne perdent pas leur données.
Pour ajouter des points manquants ici, selon la demande de Jaskey
La version de la base de données est stockée dans le fichier de base de données SQLite
.
Catch est le constructeur
SQLiteOpenHelper(Context context, String name, SQLiteDatabase.CursorFactory factory, int version)
Ainsi, lorsque le constructeur de l'assistant de base de données est appelé avec un name
(2ème paramètre), la plate-forme vérifie si la base de données existe ou non et si la base de données existe, elle obtient les informations de version de l'en-tête du fichier de base de données et déclenche le bon rappel
Comme déjà expliqué dans l'ancienne réponse, si la base de données avec le nom n'existe pas, elle déclenche onCreate
.
Explication ci-dessous explique onUpgrade
cas avec un exemple.
Disons, votre première version de l'application avait le DatabaseHelper
(s'étendant SQLiteOpenHelper
) avec le constructeur passant la version comme 1
et ensuite vous avez fourni une application mise à niveau avec le nouveau code source ayant la version passée comme 2
, puis automatiquement lorsque le DatabaseHelper
est construit, la plate-forme déclenche {[5] } en voyant version est inférieure à la version actuelle que vous avez passée.
Disons maintenant que vous prévoyez de donner une troisième version de l'application avec la version db comme 3
(la version db est augmentée uniquement lorsque le schéma de base de données doit être modifié). Dans de telles mises à niveau incrémentielles, vous devez écrire la logique de mise à niveau de chaque version de manière incrémentielle pour un meilleur code maintenable
Exemple de pseudo code ci-dessous:
@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);
}
}
Notez l'instruction break
manquante dans le cas où 1
et 2
. C'est ce que je veux dire par mise à niveau incrémentale.
Dire si l'ancienne version est 2
et la nouvelle version est 4
, alors la logique de mise à niveau de la base de données à partir de 2
à 3
, puis sur 4
Si l'ancienne version est 3
et la nouvelle version est 4
, il suffit d'exécuter la logique de mise à niveau pour 3
à 4
onCreate()
Lorsque nous créons une base de données à la première fois (C'est-à-dire que la base de données n'existe pas)
onCreate()
créez une base de données avec une version transmiseSQLiteOpenHelper(Context context, String name, SQLiteDatabase.CursorFactory factory, int version)
onCreate()
la méthode consiste à créer les tables que vous avez définies et à exécuter tout autre code que vous avez écrit. Cependant, cette méthode ne sera appelée que si le fichier SQLite est manquant dans le répertoire de données de votre application (/data/data/your.apps.classpath/databases
).Cette méthode ne sera pas appelée si vous avez changé votre code et relancé dans l'émulateur. Si vous voulez que
onCreate()
s'exécute, vous devez utiliser adb pour supprimer le fichier de base de données SQLite.
onUpgrade()
- {[7] } devrait appeler le super constructeur.
- la méthode
onUpgrade()
ne sera appelée que lorsque l'entier de version est plus grand que la version en cours d'exécution dans l'application. - Si vous voulez que la méthode
onUpgrade()
soit appelée, vous devez incrémenter le numéro de version dans votre code.
Peut-être que je suis trop tard, mais je voudrais partager ma réponse courte et douce. Veuillez vérifier Réponse pour un même problème. Il va certainement vous aider. Plus de spécifications profondes.
Si vous êtes confiant sur la syntaxe pour créer une table, cela peut arriver lorsque vous ajoutez une nouvelle colonne dans votre même table, pour cela...
1) désinstallez de votre appareil et exécutez-le à nouveau.
Ou
2) Réglage - > app - > ClearData
Ou
3) changez DATABASE_VERSION
dans votre classe "DatabaseHandler" (si vous avez ajouté une nouvelle colonne, elle sera mise à niveau automatiquement)
public DatabaseHandler(Context context) {
super(context, DATABASE_NAME, null, DATABASE_VERSION);
}
Ou
4) Change DATABASE_NAME
dans votre classe " DatabaseHandler "(j'ai rencontré le même problème. Mais je réussis en changeant DATABASE_NAME
.)
Points à retenir lors de l'extension SQLiteOpenHelper
-
super(context, DBName, null, DBversion);
- ceci devrait être invoqué première ligne du constructeur - remplacer
onCreate
etonUpgrade
(si nécessaire) -
onCreate
sera invoquée que lorsquegetWritableDatabase()
ougetReadableDatabase()
est exécuté. Et cela ne sera invoqué qu'une seule fois lorsqu'unDBName
spécifié dans la première étape n'est pas disponible. Vous pouvez ajouter une requête create table sur la méthodeonCreate
- chaque fois que vous voulez ajouter une nouvelle table, changez simplement
DBversion
et faites les requêtes dansonUpgrade
table ou simplement désinstallez puis installez l'application.
Désinstallez votre application de l'émulateur ou de l'appareil. Exécutez à nouveau l'application. (OnCreate () n'est pas exécuté lorsque la base de données existe déjà)
Aucune table de ce type n'est principalement trouvée lorsque vous n'avez pas ouvert la classe SQLiteOpenHelper
avec getwritabledata()
et avant cela, vous devez également appeler make constructor avec databasename & version.
Et OnUpgrade
est appelé chaque fois qu'il y a une valeur de mise à niveau dans le numéro de version donné dans la classe SQLiteOpenHelper
.
Ci-dessous est l'extrait de code (aucune colonne trouvée peut être à cause du sort dans le nom de la colonne):
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);
}
}
Vous pouvez créer une base de données et une table comme
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);
}
}
Remarque: Si vous voulez créer une autre table ou ajouter des colonnes ou pas de table, il suffit d'incrémenter la VERSION
Votre nom de base de données doit se terminer par .db aussi vos chaînes de requête doivent avoir un terminator (;)
Si vous oubliez de fournir une chaîne "name" comme deuxième argument au constructeur, il crée une base de données "en mémoire" qui est effacée lorsque vous fermez l'application.
OnCreate est appelé pour la première fois lorsque la création de tables est nécessaire. Nous devons remplacer cette méthode où nous écrivons le script pour la création de table qui est exécuté par SQLiteDatabase. la méthode execSQL. Après l'exécution dans le premier déploiement, cette méthode ne sera pas appelée à partir.
onUpgrade Cette méthode est appelée lorsque la version de la base de données est mise à niveau. Supposons que pour le premier déploiement, la version de base de données était 1 et que dans le deuxième déploiement, il y avait changement dans la structure de la base de données comme l'ajout d'une colonne supplémentaire dans la table. Supposons que la version de la base de données soit 2 maintenant.
Revérifiez votre requête dans votre classe DatabaseHandler / DatabaseManager (que vous avez jamais prise)
La méthode de Sqliteopenhelper a des méthodes create et upgrade, create est utilisée quand une table est créée pour la première fois et la méthode upgrade sera appelée à chaque fois que le nombre de colonne de la table est modifié.