web-dev-qa-db-fra.com

Quand SQLiteOpenHelper onCreate ()/onUpgrade () est-il exécuté?

J'ai créé mes tables dans ma SQLiteOpenHelperonCreate() mais je reçois

SQLiteException: no such table

ou

SQLiteException: no such column

les erreurs. Pourquoi?

REMARQUE:

(Ceci est le résumé fusionné de dizaines de questions similaires chaque semaine. Tenter de fournir ici une question/réponse "canonique" au wiki de la communauté, afin que toutes ces questions puissent être orientées vers une bonne référence.)

267
laalto

SQLiteOpenHelperonCreate() et onUpgrade() Les rappels sont appelés lorsque la base de données est réellement ouverte, par exemple par un appel à getWritableDatabase() . La base de données n'est pas ouverte lors de la création de l'objet assistant de base de données.

SQLiteOpenHelper versions les fichiers de base de données. Le numéro de version est l'argument int transmis à constructeur . Dans le fichier de base de données, le numéro de version est stocké dans PRAGMA user_version .

onCreate() n'est exécuté que lorsque le fichier de base de données n'existe pas et vient d'être créé. Si onCreate() renvoie avec succès (ne génère pas d'exception), la base de données est supposée être créée avec le numéro de version demandé. En conséquence, vous ne devriez pas attraper vous-même les SQLException dans onCreate().

onUpgrade() n'est appelé que 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. onUpgrade() doit mettre à jour le schéma de la table avec la version demandée.

Lorsque vous modifiez le schéma de la 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 pour que onCreate() soit exécuté à nouveau. Ceci est souvent préféré au moment du développement, lorsque vous avez le contrôle sur les versions installées et que 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 _adb uninstall your.package.name_ de Shell.

    • Effacer les données de l'application. Utilisez le gestionnaire d'applications.

  2. Incrémentez la version de la base de données afin que onUpgrade() soit appelé. Ceci est légèrement 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>") dans 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 de données dans onUpgrade() afin que vos utilisateurs ne perdent pas leurs données.

342
laalto

Pour ajouter plus de 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 d'assistance de base de données est appelé avec un name (2nd paramètre), la plateforme vérifie si la base de données existe ou non, et si la base de données existe, elle récupère les informations de version dans l'en-tête du fichier de base de données et déclenche le rappel correct.

Comme déjà expliqué dans la réponse précédente, si la base de données avec le nom n'existe pas, elle déclenche onCreate.

L'explication ci-dessous explique onUpgrade cas avec un exemple.

Disons que votre première version de l'application avait la DatabaseHelper (extension SQLiteOpenHelper) avec constructeur passant la version en tant que 1 et vous avez ensuite fourni une application mise à niveau avec le nouveau code source ayant la version passée en tant que 2, puis automatiquement lorsque la DatabaseHelper est construite, la plate-forme déclenche onUpgrade par voir le fichier existe déjà, mais la version est inférieure à la version actuelle que vous avez passée.

Supposons maintenant que vous envisagez de donner une troisième version de l'application avec la version de base de données sous la forme 3 (la version de la base de données n'augmente que 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 les cas 1 et 2. C'est ce que je veux dire par mise à niveau incrémentale.

Disons que si l'ancienne version est 2 et que la nouvelle version est 4, la logique mettra à niveau la base de données de 2 à 3, puis à 4

Si l'ancienne version est 3 et que la nouvelle version est 4, il lancera simplement la logique de mise à niveau pour 3 à 4

93
Aun

Peut-être que je suis trop tard mais je voudrais partager ma réponse courte et douce… .. S'il vous plaît vérifier Répondre pour un même problème. Il va certainement vous aider. Pas plus de spécifications profondes.

Si vous avez confiance en la syntaxe de création d'une table, cela peut arriver lorsque vous ajoutez une nouvelle colonne à votre même table, pour cela ...

1) Désinstallez à partir de votre appareil et exécutez-le à nouveau.

OR

2) Paramétrage -> application -> ClearData

OR

3) Changez DATABASE_VERSION dans votre classe "DatabaseHandler" (Si vous avez ajouté une nouvelle colonne, celle-ci sera mise à niveau automatiquement)

public DatabaseHandler(Context context) {
    super(context, DATABASE_NAME, null, DATABASE_VERSION);
}

OR

4) Changez DATABASE_NAME dans votre classe "DatabaseHandler" (J'ai rencontré le même problème. Mais j'ai réussi en changeant DATABASE_NAME.)

8
Kush

Points à retenir lors de l'extension SQLiteOpenHelper

  1. super(context, DBName, null, DBversion); - Ceci devrait être appelé en première ligne du constructeur
  2. remplacer onCreate et onUpgrade (si nécessaire)
  3. onCreate ne sera invoqué que lorsque getWritableDatabase() ou getReadableDatabase() sera exécuté. Et cela ne sera invoqué qu'une fois lorsqu'une DBName spécifiée dans la première étape n'est pas disponible. Vous pouvez ajouter une requête de création de table sur la méthode onCreate
  4. Chaque fois que vous souhaitez ajouter une nouvelle table, il suffit de changer DBversion et de faire les requêtes dans la table onUpgrade ou simplement de désinstaller puis d'installer l'application.
4
JibinNajeeb

onCreate est appelé pour la première fois lorsque la création de tables est nécessaire. Nous devons redéfinir cette méthode en écrivant le script de création de table exécuté par SQLiteDatabase. Méthode execSQL. Après avoir exécuté le premier déploiement, cette méthode ne sera plus appelée.

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 la base de données était 1 et que lors du second déploiement, la structure de la base de données a été modifiée, par exemple l'ajout d'une colonne supplémentaire dans la table. Supposons que la version de la base de données est 2 maintenant.

2

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 souhaitez créer une autre table ou ajouter des colonnes ou aucune table de ce type, incrémentez simplement la VERSION

2
Enamul Haque

Si vous oubliez de fournir une chaîne "name" en tant que second argument du constructeur, une base de données "en mémoire" est créée, laquelle est effacée lorsque vous fermez l'application.

1
phreakhead

aucune table de ce type n’est trouvée principalement lorsque vous n’avez pas ouvert la classe SQLiteOpenHelper avec getwritabledata() et avant cela, vous devez également appeler le constructeur make avec le nom de base de données et la version. Et OnUpgrade est appelé chaque fois que la valeur de la mise à niveau est indiquée dans le numéro de version indiqué dans la classe SQLiteOpenHelper.

Ci-dessous l'extrait de code (aucune colonne de ce type n'a été trouvée en raison de l'épellation 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);
    }

}
1
Bharat Lalwani

Revérifiez votre requête dans la classe DatabaseHandler/DatabaseManager (quelle que soit votre position)

0
venu

Désinstallez votre application de l'émulateur ou du périphérique. Exécutez l'application à nouveau. (OnCreate () n'est pas exécuté lorsque la base de données existe déjà)

0
Nand gopal

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

0
Omer Haqqani

Base de données SQLite remplacer deux méthodes 

1) onCreate (): Cette méthode n’a été invoquée qu’une fois lorsque l’application est lancée pour la première fois. Donc, il a appelé une seule fois 

2) onUpgrade () Cette méthode appelée lorsque nous modifions la version de la base de données, cette méthode est appelée. Elle est utilisée pour modifier la structure de la table, comme pour ajouter une nouvelle colonne après la création du schéma de base de données

0
sushant suryawanshi