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.)

252
demandé sur laalto 2014-02-19 17:31:07

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 SQLExceptions 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:

  1. 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.

  2. 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 appeler onCreate() 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.

325
répondu laalto 2014-02-19 13:31:07

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

88
répondu Aun 2017-02-14 12:35:36

onCreate()

  1. 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 transmise SQLiteOpenHelper(Context context, String name, SQLiteDatabase.CursorFactory factory, int version)

  2. 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).

  3. 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()

  1. {[7] } devrait appeler le super constructeur.
  2. 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.
  3. Si vous voulez que la méthode onUpgrade() soit appelée, vous devez incrémenter le numéro de version dans votre code.
18
répondu jeet parmar 2017-01-03 14:52:36

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.)

6
répondu shital 2017-05-23 12:18:24

Points à retenir lors de l'extension SQLiteOpenHelper

  1. super(context, DBName, null, DBversion); - ceci devrait être invoqué première ligne du constructeur
  2. remplacer onCreate et onUpgrade (si nécessaire)
  3. onCreate sera invoquée que lorsque getWritableDatabase() ou getReadableDatabase() est exécuté. Et cela ne sera invoqué qu'une seule fois lorsqu'un DBName spécifié dans la première étape n'est pas disponible. Vous pouvez ajouter une requête create table sur la méthode onCreate
  4. chaque fois que vous voulez ajouter une nouvelle table, changez simplement DBversion et faites les requêtes dans onUpgrade table ou simplement désinstallez puis installez l'application.
3
répondu JibinNajeeb 2016-10-31 19:48:13

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à)

0
répondu Nand gopal 2016-03-11 11:32:27

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

}
0
répondu Bharat Lalwani 2017-07-04 10:39:21

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

0
répondu Enamul Haque 2017-07-04 18:51:09

Votre nom de base de données doit se terminer par .db aussi vos chaînes de requête doivent avoir un terminator (;)

0
répondu Omer Haqqani 2017-08-01 08:08:06

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.

0
répondu phreakhead 2017-09-28 04:52:48

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.

0
répondu Faxriddin Abdullayev 2018-01-15 07:49:56

Revérifiez votre requête dans votre classe DatabaseHandler / DatabaseManager (que vous avez jamais prise)

0
répondu venu 2018-10-04 07:30:18

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é.

-2
répondu Vishwa Pratap 2016-12-30 16:54:01