I have created DatabaseHelper to make my development easier. If my Database version is upgrade from 1 to 2, onUpgrade will called and table will be dropped. I wonder will this cause my data stored in table dropped too? I means, will I lost my data stored in table?
Here's the code.
private static class DatabaseHelper extends SQLiteOpenHelper {
DatabaseHelper(Context context) {
super(context, DATABASE_NAME, null, DATABASE_VERSION);
}
#Override
public void onCreate(SQLiteDatabase db) {
db.execSQL(DATABASE_CREATE);
}
#Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
Log.w(TAG, "Upgrading database from version " + oldVersion + " to "
+ newVersion + ", which will destroy all old data");
db.execSQL("DROP TABLE IF EXISTS notes");
onCreate(db);
}
}
By looking at your code, Yes you will lose the current table of the database and a new empty table notes will be created.
So the best way to upgrade the database is before this:
db.execSQL("DROP TABLE IF EXISTS notes");
statement, you should made a backup of your current database (easiest way is to rename the table) and then drop the current table to create the new one.
It is always a good programming practice to keep a backup of information before editing/upgrading it.
When you drop a table all it's data is deleted too. If you want to keep it, rename the table first, create the new one and then select the data from the old into the new one.
You can alter table in onUpgrade method if there is change in coloumn. If you want to make fresh table then only call Drop inside onUpgrade, if there is no change in schema dont do anything inside onUpgrade method.
Related
Is it possible to delete any existing data set by a previous install of same app (databse tables and shared preferences etc) when the app is re-installed?
I have an app that stores some values in sqlite database, if the app is re-installed without prior properly uninstalling. I face problems from previous database entries etc.
If uninstalling the app didn't do the stuff try this :
System Parameters -> Manage Applications -> Your Application -> Clear data
If you click on the button (Clear data) you will see a dialog which shows you what kind of data will be cleared.
Edit:
If you want to do that programmatically, you can :
Change database version in the super method of the constructor:
super(context, DATABASE_NAME, null, NEW_DB_VERSION);
Add a drop statement before creating tables.
database.execSQL("DROP TABLE IF EXISTS your_table");
database.execSQL(" CREATE TABLE your_table ...");
Proceed to a hard drop of the database:
this.context.deleteDatabase(YOUR_DATABASE_NAME;
Its very Simple.
First Delete the table using drop query
sdb.execSQL("DROP TABLE IF EXISTS tablename");
and then again use the create table query
sdb.execSQL(" CREATE TABLE tablename(col1 TEXT PRIMARY KEY)");
or
delete the DB file using file explorer in path data->data->package->databases->dbname
update the Database version to greater value in the OpenHelper, it will automatically drop all the tables in database and recreate them.
For shared preferences.. you can clear them from the OpenHelper when onUpgrade is called.
Like Ankit Popli said, Using version is the right way to go:
public class Database extends SQLiteOpenHelper{
private static final int DATABASE_VERSION = 1;
public static final String DATABASE_NAME = "YourDBName.db";
#Override
public void onCreate(SQLiteDatabase db) {
db.execSQL(CREATE_TABLE);
}
#Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
// ALl the deletion operation here.
db.execSQL("DROP TABLE IF EXISTS "+Database.TABLE);
onCreate(db);
}
}
AndroidSqlite will automatically call onUpgrade function when the version number is incremented. Do all the database deletion there.
I want the sqlite database of my app to be cleared each time the application is updated.
To do that, I make a drop table query on all my tables, in the "onUpgrade" function of SQLiteDatabase.
I got 2 problems:
- at the first launch of my app, I don't do any special.
- at the second launch, I add a "setVersion(2)" line. It calls the onUpgrade method but the logs are strange:
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion){
Log.d("GDB", "onUpgrade "+oldVersion+" -> "+newVersion);
}
----------------------------------------------------------
DEBUG/GDB(5928): onUpgrade 2 -> 1
So when I make a setVersion(), the 2 versions seems to be switched.....
My second problem is that is I launch my app a third time, without changing the code ( so the setVersion(2) is already here), the onUpgrade method is called again! Did I miss something to definitively set the version to 2?
I don't think you should be setting the version of the database in code directly using the setVersion method. Instead you should pass the schema version into the constructor of your SQLiteOpenHelper (or at least your class which extends this). Your onUpgrade method should then contain condition statements to decide what to run depending on what version the user is upgrading from. These conditions should form a cascade so that coming from a low version applies in sequence all database updates required to get the user to the current level.
So when you want to change your schema, you add a new condition to your onUpgrade and up the schema version passed to your constructor.
This is what the constructor in the OpenHelper looks like:
public TiftHelper(Context context) {
super(context, DATABASE_NAME, null, SCHEMA_VERSION);
}
Then the onUpgrade looks something like this:
#Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
Log.d(TAG, "on upgrade called. Old version:" + oldVersion
+ ". New version:" + newVersion);
if (oldVersion == 19) {
db.execSQL("create table challenges_temp as select * from challenges;");
db.execSQL("drop table challenges;");
db.execSQL(create_challenges);
db.execSQL("insert into challenges (_id, name, is_predef, status) select _id, name, is_predef, 'IN_PROGRESS' from challenges_temp");
db.execSQL("drop table challenges_temp;");
}
if (oldVersion <= 20) {
// adding the status column to the challenges table
db.execSQL("create table challenges_temp as select * from challenges;");
db.execSQL("drop table challenges;");
db.execSQL(create_challenges);
db.execSQL("insert into challenges (_id, name, is_predef, status) select _id, name, is_predef, 'IN_PROGRESS' from challenges_temp");
db.execSQL("drop table challenges_temp;");
}
etc.
That works fine for me.
I am trying to upgrade a certain table by adding a column to a Sqlite table in my android app.I have added an alter table statement in the onUpgrade method of my DBHelper.
Here are the problems that I am seeing
I changed the value of Database version from 1 to 2, so ideally now the onUpgrade should get called.It does get called, but it gets called everytime I instantiate the class.As a result I get a column already exists error.
Here is the onUpgrade method
#Override
public void onUpgrade(SQLiteDatabase db, int oldVersion,
int newVersion)
{
Log.d("old Version",oldVersion+"");
Log.d("New Version",newVersion+"");
db.beginTransaction();
try
{
String DATABASE_UPGRADE;
DATABASE_UPGRADE="alter table "+DATABASE_TABLE_MESSAGES+" ADD COLUMN "+ IS_READ+ " integer DEFAULT 0;";
db.execSQL(DATABASE_UPGRADE);
Log.d("upgrade", "Successful");
db.setTransactionSuccessful();
}
finally
{
db.endTransaction();
}
}
}
I am wondering why the onUpgrade gets called each time!!!
In the constructor of your database helper are you correctly passing the new version number?
EDIT: should look like this
DatabaseHelper(Context context)
{
super(context, DATABASE_NAME, null, DATABASE_VERSION);
}
and DATABASE_VERSION should be 2.
I have an application in which i am trying to create a Database. On the first run the application works properly. Subsequent launch of the application it crashes. The error is because the application is trying to create the db again.
So i want to know how to create a database or tables only if they dont exists or only if the application is run the first time.
You can extend the class SQLiteOpenHelper to handle different versions of your database. Here is an example:
public class MyDbOpenHelper extends **SQLiteOpenHelper** {
final static int VERSION = 2;
public MyDbOpenHelper(Context context, String dbname) {
super(context, dbname, null, VERSION);
}
#Override
public void **onCreate**(SQLiteDatabase db) {
/* TODO SQL-Queries for new Database */
}
#Override
public void **onUpgrade**(SQLiteDatabase db, int oldVersion, int newVersion) {
/* SQL-Queries t*/
if (oldVersion < 2) {
db.execSQL("ALTER TABLE my_table ADD COLUMN new_attrubte INTEGER");
}
}
}
Handle of database is new in onCreate and if it exist, onUpgrade is called with existing version number in oldVersion parameter.
SQLite has a CREATE TABLE IF NOT EXISTS command. You could try that.
It is usually an error to attempt to create a new table in a database that already contains a table, index or view of the same name. However, if the "IF NOT EXISTS" clause is specified as part of the CREATE TABLE statement and a table or view of the same name already exists, the CREATE TABLE command simply has no effect (and no error message is returned). An error is still returned if the table cannot be created because of an existing index, even if the "IF NOT EXISTS" clause is specified.
Typically, for a WinForm or a Web App, I create the database and tables through the RDBMS or through a separate install process. However, I haven't seen anything of the sort in Android. All the examples I've seen have the database creation scripts embedded in an activity like this.
The best thing I can come up with now is to call a method from the data access constructor to check whether the database is installed - if not - install it. However, this seems like a lot of overhead to me.
What's the cleanest way to execute a android database install and then forget about it?
When using SQLLiteOpenHelper (http://developer.android.com/reference/android/database/sqlite/SQLiteOpenHelper.html), the onCreate method will be called only if the database doesn't exist. onUpgrade will be called when a new version of the database is introduced.
IF the database already exists, and no version upgrade occured, these methods won't be executed.
There is no need for implementing if-else checks in your activity.
private static class DatabaseHelper extends SQLiteOpenHelper
{
DatabaseHelper(Context context)
{
super(context, DATABASE_NAME, null, DATABASE_VERSION);
}
#Override
public void onCreate(SQLiteDatabase db)
{
db.execSQL(DATABASE_CREATE);
}
#Override
public void onUpgrade(SQLiteDatabase db, int oldVersion,
int newVersion)
{
Log.w(TAG, "Upgrading database from version " + oldVersion + " to " + newVersion);
db.execSQL(DATABASE_UPGRADE);
}
}