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.)
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
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 backAs 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
(extendingSQLiteOpenHelper
) with constructor passing version as1
and then you provided an upgraded application with the new source code having version passed as2
, then automatically when theDatabaseHelper
is constructed, platform triggersonUpgrade
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 codeExample pseudo code below:
Notice the missing
break
statement in case1
and2
. This is what I mean by incremental upgrade.Say if the old version is
2
and new version is4
, then the logic will upgrade the database from2
to3
and then to4
If old version is
3
and new version is4
, it will just run the upgrade logic for3
to4
SQLiteOpenHelper
onCreate()
andonUpgrade()
callbacks are invoked when the database is actually opened, for example by a call togetWritableDatabase()
. The database is not opened when the database helper object itself is created.SQLiteOpenHelper
versions the database files. The version number is theint
argument passed to the constructor. In the database file, the version number is stored inPRAGMA user_version
.onCreate()
is only run when the database file did not exist and was just created. IfonCreate()
returns successfully (doesn't throw an exception), the database is assumed to be created with the requested version number. As an implication, you should not catchSQLException
s inonCreate()
yourself.onUpgrade()
is only called when the database file exists but the stored version number is lower than requested in constructor. TheonUpgrade()
should update the table schema to the requested version.When changing the table schema in code (
onCreate()
), you should make sure the database is updated. Two main approaches:Delete the old database file so that
onCreate()
is run again. This is often preferred at development time where you have control over the installed versions and data loss is not an issue. Some ways to to delete the database file:Uninstall the application. Use the application manager or
adb uninstall your.package.name
from shell.Clear application data. Use the application manager.
Increment the database version so that
onUpgrade()
is invoked. This is slightly more complicated as more code is needed.For development time schema upgrades where data loss is not an issue, you can just use
execSQL("DROP TABLE IF EXISTS <tablename>")
in to remove your existing tables and callonCreate()
to recreate the database.For released versions, you should implement data migration in
onUpgrade()
so your users don't lose their data.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.
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.
Uninstall your application from the emulator or device. Run the app again. (OnCreate() is not executed when the database already exists)
Recheck your query in ur DatabaseHandler/DatabaseManager class(which ever you have took)