[android] When does SQLiteOpenHelper onCreate() / onUpgrade() run?

I have created my tables in my SQLiteOpenHelper onCreate() but receive

SQLiteException: no such table

or

SQLiteException: no such column

errors. Why?

NOTE:

(This is the amalgamated summary of tens of similar questions every week. Attempting to provide a "canonical" community wiki question/answer here so that all those questions can be directed to a good reference.)

The answer is


Your database name must end with .db also your query strings must have a terminator (;)


onCreate is called for the first time when creation of tables are needed. We need to override this method where we write the script for table creation which is executed by SQLiteDatabase. execSQL method. After executing in first time deployment, this method will not be called onwards.

onUpgrade This method is called when database version is upgraded. Suppose for the first time deployment , database version was 1 and in second deployment there was change in database structure like adding extra column in table. Suppose database version is 2 now.


Points to remember when extending SQLiteOpenHelper

  1. super(context, DBName, null, DBversion); - This should be invoked first line of constructor
  2. override onCreate and onUpgrade (if needed)
  3. onCreate will be invoked only when getWritableDatabase() or getReadableDatabase() is executed. And this will only invoked once when a DBName specified in the first step is not available. You can add create table query on onCreate method
  4. Whenever you want to add new table just change DBversion and do the queries in onUpgrade table or simply uninstall then install the app.

In my case I get items from XML-file with <string-array>, where I store <item>s. In these <item>s I hold SQL strings and apply one-by-one with databaseBuilder.addMigrations(migration). I made one mistake, forgot to add \ before quote and got the exception:

android.database.sqlite.SQLiteException: no such column: some_value (code 1 SQLITE_ERROR): , while compiling: INSERT INTO table_name(id, name) VALUES(1, some_value)

So, this is a right variant:

<item>
    INSERT INTO table_name(id, name) VALUES(1, \"some_value\")
</item>

onCreate()

  1. When we create DataBase at a first time (i.e Database is not exists) onCreate() create database with version which is passed in SQLiteOpenHelper(Context context, String name, SQLiteDatabase.CursorFactory factory, int version)

  2. onCreate() method is creating the tables you’ve defined and executing any other code you’ve written. However, this method will only be called if the SQLite file is missing in your app’s data directory (/data/data/your.apps.classpath/databases).

  3. This method will not be called if you’ve changed your code and relaunched in the emulator. If you want onCreate() to run you need to use adb to delete the SQLite database file.

onUpgrade()

  1. SQLiteOpenHelper should call the super constructor.
  2. The onUpgrade() method will only be called when the version integer is larger than the current version running in the app.
  3. If you want the onUpgrade() method to be called, you need to increment the version number in your code.

no such table found is mainly when you have not opened the SQLiteOpenHelper class with getwritabledata() and before this you also have to call make constructor with databasename & version. And OnUpgrade is called whenever there is upgrade value in version number given in SQLiteOpenHelper class.

Below is the code snippet (No such column found may be because of spell in column name):

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

}

You can create database & table like

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

Note : if you want create another table or add columns or no such table, just increment the VERSION


To further add missing points here, as per the request by Jaskey

Database version is stored within the SQLite database file.

catch is the constructor

SQLiteOpenHelper(Context context, String name, SQLiteDatabase.CursorFactory factory, int version)

So when the database helper constructor is called with a name (2nd param), platform checks if the database exists or not and if the database exists, it gets the version information from the database file header and triggers the right call back

As already explained in the older answer, if the database with the name doesn't exists, it triggers onCreate.

Below explanation explains onUpgrade case with an example.

Say, your first version of application had the DatabaseHelper (extending SQLiteOpenHelper) with constructor passing version as 1 and then you provided an upgraded application with the new source code having version passed as 2, then automatically when the DatabaseHelper is constructed, platform triggers onUpgrade by seeing the file already exists, but the version is lower than the current version which you have passed.

Now say you are planing to give a third version of application with db version as 3 (db version is increased only when database schema is to be modified). In such incremental upgrades, you have to write the upgrade logic from each version incrementally for a better maintainable code

Example pseudo code below:

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

Notice the missing break statement in case 1 and 2. This is what I mean by incremental upgrade.

Say if the old version is 2 and new version is 4, then the logic will upgrade the database from 2 to 3 and then to 4

If old version is 3 and new version is 4, it will just run the upgrade logic for 3 to 4


Sqlite database override two methods

1) onCreate(): This method invoked only once when the application is start at first time . So it called only once

2)onUpgrade() This method called when we change the database version,then this methods gets invoked.It is used for the alter the table structure like adding new column after creating DB Schema


If you forget to provide a "name" string as the second argument to the constructor, it creates an "in-memory" database which gets erased when you close the app.


Sqliteopenhelper's method have methods create and upgrade,create is used when any table is first time created and upgrade method will called everytime whenever table's number of column is changed.


Uninstall your application from the emulator or device. Run the app again. (OnCreate() is not executed when the database already exists)


May be I am too late but I would like to share my short and sweet answer. Please check Answer for a same problem. It will definitely help you. No more deep specifications.

If you are confident about syntax for creating table, than it may happen when you add new column in your same table, for that...

1) Uninstall from your device and run it again.

OR

2) Setting -> app -> ClearData

OR

3) Change DATABASE_VERSION in your "DatabaseHandler" class (If you have added new column than it will upgrade automatically)

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

OR

4) Change DATABASE_NAME in your "DatabaseHandler" class (I faced same problem. But I succeed by changing DATABASE_NAME.)


Recheck your query in ur DatabaseHandler/DatabaseManager class(which ever you have took)


Examples related to android

Under what circumstances can I call findViewById with an Options Menu / Action Bar item? How to implement a simple scenario the OO way My eclipse won't open, i download the bundle pack it keeps saying error log getting " (1) no such column: _id10 " error java doesn't run if structure inside of onclick listener Cannot retrieve string(s) from preferences (settings) strange error in my Animation Drawable how to put image in a bundle and pass it to another activity FragmentActivity to Fragment A failure occurred while executing com.android.build.gradle.internal.tasks

Examples related to sqlite

getting " (1) no such column: _id10 " error Laravel: PDOException: could not find driver auto create database in Entity Framework Core How to open .SQLite files Accessing an SQLite Database in Swift When does SQLiteOpenHelper onCreate() / onUpgrade() run? Attempt to write a readonly database - Django w/ SELinux error Android sqlite how to check if a record exists How can I add the sqlite3 module to Python? "Insert if not exists" statement in SQLite

Examples related to android-sqlite

When does SQLiteOpenHelper onCreate() / onUpgrade() run? How to get row count in sqlite using Android? Set default value of an integer column SQLite View contents of database file in Android Studio android.database.sqlite.SQLiteCantOpenDatabaseException: unknown error (code 14): Could not open database How to access data/data folder in Android device? How to perform an SQLite query within an Android application? Ship an application with a database

Examples related to sqlexception

Transaction count after EXECUTE indicates a mismatching number of BEGIN and COMMIT statements. Previous count = 1, current count = 0 When does SQLiteOpenHelper onCreate() / onUpgrade() run? Java java.sql.SQLException: Invalid column index on preparing statement java.sql.SQLException: Incorrect string value: '\xF0\x9F\x91\xBD\xF0\x9F...' What does "if (rs.next())" mean? How to catch a specific SqlException error? java.sql.SQLException: No suitable driver found for jdbc:microsoft:sqlserver conversion of a varchar data type to a datetime data type resulted in an out-of-range value

Examples related to sqliteopenhelper

When does SQLiteOpenHelper onCreate() / onUpgrade() run? Android SQLite Example