Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

SQLite add column, keep data

Tags:

android

sqlite

I have a database with 4 columns:

@Override public void onCreate(SQLiteDatabase database) {         database.execSQL("CREATE TABLE " + DATABASENAME + " (name TEXT, latitude REAL, longitude REAL, country TEXT);"); } 

Now I want to add another column, but keep the rows that are already in the database. How should I do this? I can't find any useful references to this.

@Override public void onUpgrade(SQLiteDatabase db, int arg1, int arg2) {     //What to do here? } 

EDIT

I have modified my onCreate to:

@Override public void onCreate(SQLiteDatabase database) {     database.execSQL("CREATE TABLE " + DATABASENAME + " (name TEXT, latitude REAL, longitude REAL, country TEXT, code TEXT);"); } 

and my onUpgrade to:

@Override public void onUpgrade(SQLiteDatabase db, int arg1, int arg2) {     Logger.log("Updating userstations database from " + arg1 + " to " + arg2 + ".");     if (arg1 == 2 && arg2 == 3) {         db.execSQL("ALTER TABLE " + DATABASENAME + " ADD COLUMN code TEXT;");     } else if(arg1 == 1){         db.execSQL("DROP TABLE IF EXISTS " + DATABASENAME);     }     onCreate(db); } 

However, now I get this stacktrace:

10-01 21:24:19.581: ERROR/Database(21434): Failure 1 (table userstations already exists) on 0x19c378 when preparing 'CREATE TABLE userstations (name TEXT, latitude REAL, longitude REAL, country TEXT, code TEXT);'. 10-01 21:24:19.611: ERROR/SQLiteOpenHelper(21434): Couldn't open userstations for writing (will try read-only): 10-01 21:24:19.611: ERROR/SQLiteOpenHelper(21434): android.database.sqlite.SQLiteException: table userstations already exists: CREATE TABLE userstations (name TEXT, latitude REAL, longitude REAL, country TEXT, code TEXT); 10-01 21:24:19.611: ERROR/SQLiteOpenHelper(21434):     at android.database.sqlite.SQLiteDatabase.native_execSQL(Native Method) 10-01 21:24:19.611: ERROR/SQLiteOpenHelper(21434):     at android.database.sqlite.SQLiteDatabase.execSQL(SQLiteDatabase.java:1763) 10-01 21:24:19.611: ERROR/SQLiteOpenHelper(21434):     at com.myapp.myapp.databases.UserStationsOpenHelper.onCreate(UserStationsOpenHelper.java:25) 10-01 21:24:19.611: ERROR/SQLiteOpenHelper(21434):     at com.myapp.myapp.databases.UserStationsOpenHelper.onUpgrade(UserStationsOpenHelper.java:36) 10-01 21:24:19.611: ERROR/SQLiteOpenHelper(21434):     at android.database.sqlite.SQLiteOpenHelper.getWritableDatabase(SQLiteOpenHelper.java:132) 10-01 21:24:19.611: ERROR/SQLiteOpenHelper(21434):     at android.database.sqlite.SQLiteOpenHelper.getReadableDatabase(SQLiteOpenHelper.java:187) 10-01 21:24:19.611: ERROR/SQLiteOpenHelper(21434):     at com.myapp.myapp.databases.UserStationsOpenHelper.getStations(UserStationsOpenHelper.java:43) 10-01 21:24:19.611: ERROR/SQLiteOpenHelper(21434):     at com.myapp.myapp.Data.readUserStations(Data.java:369) 10-01 21:24:19.611: ERROR/SQLiteOpenHelper(21434):     at com.myapp.myapp.Data.getUserStations(Data.java:210) 10-01 21:24:19.611: ERROR/SQLiteOpenHelper(21434):     at com.myapp.myapp.stationstab.StationsActivity.newStations(StationsActivity.java:190) 10-01 21:24:19.611: ERROR/SQLiteOpenHelper(21434):     at com.myapp.myapp.stationstab.StationsActivity.refresh(StationsActivity.java:129) 10-01 21:24:19.611: ERROR/SQLiteOpenHelper(21434):     at com.myapp.myapp.stationstab.StationsActivity.onCreate(StationsActivity.java:108) 10-01 21:24:19.611: ERROR/SQLiteOpenHelper(21434):     at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1047) 10-01 21:24:19.611: ERROR/SQLiteOpenHelper(21434):     at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:1722) 10-01 21:24:19.611: ERROR/SQLiteOpenHelper(21434):     at android.app.ActivityThread.startActivityNow(ActivityThread.java:1598) 10-01 21:24:19.611: ERROR/SQLiteOpenHelper(21434):     at android.app.LocalActivityManager.moveToState(LocalActivityManager.java:127) 10-01 21:24:19.611: ERROR/SQLiteOpenHelper(21434):     at android.app.LocalActivityManager.startActivity(LocalActivityManager.java:339) 10-01 21:24:19.611: ERROR/SQLiteOpenHelper(21434):     at com.myapp.myapp.stationstab.StationsActivityGroup.onCreate(StationsActivityGroup.java:38) 10-01 21:24:19.611: ERROR/SQLiteOpenHelper(21434):     at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1047) 10-01 21:24:19.611: ERROR/SQLiteOpenHelper(21434):     at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:1722) 10-01 21:24:19.611: ERROR/SQLiteOpenHelper(21434):     at android.app.ActivityThread.startActivityNow(ActivityThread.java:1598) 10-01 21:24:19.611: ERROR/SQLiteOpenHelper(21434):     at android.app.LocalActivityManager.moveToState(LocalActivityManager.java:127) 10-01 21:24:19.611: ERROR/SQLiteOpenHelper(21434):     at android.app.LocalActivityManager.startActivity(LocalActivityManager.java:339) 10-01 21:24:19.611: ERROR/SQLiteOpenHelper(21434):     at android.widget.TabHost$IntentContentStrategy.getContentView(TabHost.java:654) 10-01 21:24:19.611: ERROR/SQLiteOpenHelper(21434):     at android.widget.TabHost.setCurrentTab(TabHost.java:326) 10-01 21:24:19.611: ERROR/SQLiteOpenHelper(21434):     at android.widget.TabHost.addTab(TabHost.java:216) 10-01 21:24:19.611: ERROR/SQLiteOpenHelper(21434):     at com.myapp.myapp.TreinVerkeer.setupTab(TreinVerkeer.java:131) 10-01 21:24:19.611: ERROR/SQLiteOpenHelper(21434):     at com.myapp.myapp.TreinVerkeer.initTabs(TreinVerkeer.java:108) 10-01 21:24:19.611: ERROR/SQLiteOpenHelper(21434):     at com.myapp.myapp.TreinVerkeer.onCreate(TreinVerkeer.java:62) 10-01 21:24:19.611: ERROR/SQLiteOpenHelper(21434):     at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1047) 10-01 21:24:19.611: ERROR/SQLiteOpenHelper(21434):     at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:1722) 10-01 21:24:19.611: ERROR/SQLiteOpenHelper(21434):     at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:1784) 10-01 21:24:19.611: ERROR/SQLiteOpenHelper(21434):     at android.app.ActivityThread.access$1500(ActivityThread.java:123) 10-01 21:24:19.611: ERROR/SQLiteOpenHelper(21434):     at android.app.ActivityThread$H.handleMessage(ActivityThread.java:939) 10-01 21:24:19.611: ERROR/SQLiteOpenHelper(21434):     at android.os.Handler.dispatchMessage(Handler.java:99) 10-01 21:24:19.611: ERROR/SQLiteOpenHelper(21434):     at android.os.Looper.loop(Looper.java:123) 10-01 21:24:19.611: ERROR/SQLiteOpenHelper(21434):     at android.app.ActivityThread.main(ActivityThread.java:3835) 10-01 21:24:19.611: ERROR/SQLiteOpenHelper(21434):     at java.lang.reflect.Method.invokeNative(Native Method) 10-01 21:24:19.611: ERROR/SQLiteOpenHelper(21434):     at java.lang.reflect.Method.invoke(Method.java:507) 10-01 21:24:19.611: ERROR/SQLiteOpenHelper(21434):     at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:841) 10-01 21:24:19.611: ERROR/SQLiteOpenHelper(21434):     at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:599) 10-01 21:24:19.611: ERROR/SQLiteOpenHelper(21434):     at dalvik.system.NativeStart.main(Native Method) 10-01 21:24:19.621: DEBUG/AndroidRuntime(21434): Shutting down VM 10-01 21:24:19.621: WARN/dalvikvm(21434): threadid=1: thread exiting with uncaught exception (group=0x4018a560) 10-01 21:24:19.641: ERROR/AndroidRuntime(21434): FATAL EXCEPTION: main 10-01 21:24:19.641: ERROR/AndroidRuntime(21434): java.lang.RuntimeException: Unable to start activity ComponentInfo{com.myapp.myapp/com.myapp.myapp.TreinVerkeer}: java.lang.RuntimeException: Unable to start activity ComponentInfo{com.myapp.myapp/com.myapp.myapp.stationstab.StationsActivityGroup}: java.lang.RuntimeException: Unable to start activity ComponentInfo{com.myapp.myapp/com.myapp.myapp.stationstab.StationsActivity}: android.database.sqlite.SQLiteException: Can't upgrade read-only database from version 2 to 3: /data/data/com.myapp.myapp/databases/userstations 10-01 21:24:19.641: ERROR/AndroidRuntime(21434):     at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:1768) 10-01 21:24:19.641: ERROR/AndroidRuntime(21434):     at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:1784) 10-01 21:24:19.641: ERROR/AndroidRuntime(21434):     at android.app.ActivityThread.access$1500(ActivityThread.java:123) 10-01 21:24:19.641: ERROR/AndroidRuntime(21434):     at android.app.ActivityThread$H.handleMessage(ActivityThread.java:939) 10-01 21:24:19.641: ERROR/AndroidRuntime(21434):     at android.os.Handler.dispatchMessage(Handler.java:99) 10-01 21:24:19.641: ERROR/AndroidRuntime(21434):     at android.os.Looper.loop(Looper.java:123) 10-01 21:24:19.641: ERROR/AndroidRuntime(21434):     at android.app.ActivityThread.main(ActivityThread.java:3835) 10-01 21:24:19.641: ERROR/AndroidRuntime(21434):     at java.lang.reflect.Method.invokeNative(Native Method) 10-01 21:24:19.641: ERROR/AndroidRuntime(21434):     at java.lang.reflect.Method.invoke(Method.java:507) 10-01 21:24:19.641: ERROR/AndroidRuntime(21434):     at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:841) 10-01 21:24:19.641: ERROR/AndroidRuntime(21434):     at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:599) 10-01 21:24:19.641: ERROR/AndroidRuntime(21434):     at dalvik.system.NativeStart.main(Native Method) 10-01 21:24:19.641: ERROR/AndroidRuntime(21434): Caused by: java.lang.RuntimeException: Unable to start activity ComponentInfo{com.myapp.myapp/com.myapp.myapp.stationstab.StationsActivityGroup}: java.lang.RuntimeException: Unable to start activity ComponentInfo{com.myapp.myapp/com.myapp.myapp.stationstab.StationsActivity}: android.database.sqlite.SQLiteException: Can't upgrade read-only database from version 2 to 3: /data/data/com.myapp.myapp/databases/userstations 10-01 21:24:19.641: ERROR/AndroidRuntime(21434):     at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:1768) 10-01 21:24:19.641: ERROR/AndroidRuntime(21434):     at android.app.ActivityThread.startActivityNow(ActivityThread.java:1598) 10-01 21:24:19.641: ERROR/AndroidRuntime(21434):     at android.app.LocalActivityManager.moveToState(LocalActivityManager.java:127) 10-01 21:24:19.641: ERROR/AndroidRuntime(21434):     at android.app.LocalActivityManager.startActivity(LocalActivityManager.java:339) 10-01 21:24:19.641: ERROR/AndroidRuntime(21434):     at android.widget.TabHost$IntentContentStrategy.getContentView(TabHost.java:654) 10-01 21:24:19.641: ERROR/AndroidRuntime(21434):     at android.widget.TabHost.setCurrentTab(TabHost.java:326) 10-01 21:24:19.641: ERROR/AndroidRuntime(21434):     at android.widget.TabHost.addTab(TabHost.java:216) 10-01 21:24:19.641: ERROR/AndroidRuntime(21434):     at com.myapp.myapp.TreinVerkeer.setupTab(TreinVerkeer.java:131) 10-01 21:24:19.641: ERROR/AndroidRuntime(21434):     at com.myapp.myapp.TreinVerkeer.initTabs(TreinVerkeer.java:108) 10-01 21:24:19.641: ERROR/AndroidRuntime(21434):     at com.myapp.myapp.TreinVerkeer.onCreate(TreinVerkeer.java:62) 10-01 21:24:19.641: ERROR/AndroidRuntime(21434):     at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1047) 10-01 21:24:19.641: ERROR/AndroidRuntime(21434):     at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:1722) 10-01 21:24:19.641: ERROR/AndroidRuntime(21434):     ... 11 more 10-01 21:24:19.641: ERROR/AndroidRuntime(21434): Caused by: java.lang.RuntimeException: Unable to start activity ComponentInfo{com.myapp.myapp/com.myapp.myapp.stationstab.StationsActivity}: android.database.sqlite.SQLiteException: Can't upgrade read-only database from version 2 to 3: /data/data/com.myapp.myapp/databases/userstations 10-01 21:24:19.641: ERROR/AndroidRuntime(21434):     at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:1768) 10-01 21:24:19.641: ERROR/AndroidRuntime(21434):     at android.app.ActivityThread.startActivityNow(ActivityThread.java:1598) 10-01 21:24:19.641: ERROR/AndroidRuntime(21434):     at android.app.LocalActivityManager.moveToState(LocalActivityManager.java:127) 10-01 21:24:19.641: ERROR/AndroidRuntime(21434):     at android.app.LocalActivityManager.startActivity(LocalActivityManager.java:339) 10-01 21:24:19.641: ERROR/AndroidRuntime(21434):     at com.myapp.myapp.stationstab.StationsActivityGroup.onCreate(StationsActivityGroup.java:38) 10-01 21:24:19.641: ERROR/AndroidRuntime(21434):     at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1047) 10-01 21:24:19.641: ERROR/AndroidRuntime(21434):     at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:1722) 10-01 21:24:19.641: ERROR/AndroidRuntime(21434):     ... 22 more 10-01 21:24:19.641: ERROR/AndroidRuntime(21434): Caused by: android.database.sqlite.SQLiteException: Can't upgrade read-only database from version 2 to 3: /data/data/com.myapp.myapp/databases/userstations 10-01 21:24:19.641: ERROR/AndroidRuntime(21434):     at android.database.sqlite.SQLiteOpenHelper.getReadableDatabase(SQLiteOpenHelper.java:199) 10-01 21:24:19.641: ERROR/AndroidRuntime(21434):     at com.myapp.myapp.databases.UserStationsOpenHelper.getStations(UserStationsOpenHelper.java:43) 10-01 21:24:19.641: ERROR/AndroidRuntime(21434):     at com.myapp.myapp 
like image 505
nhaarman Avatar asked Oct 01 '11 18:10

nhaarman


People also ask

How do I add a new column in SQLite?

Syntax. The syntax to ADD A COLUMN in a table in SQLite (using the ALTER TABLE statement) is: ALTER TABLE table_name ADD new_column_name column_definition; table_name.

Does SQLite persist data?

Sqlite Database commonly used to persist the data in most Android applications. Sqlite file is created in your package folder. Sqlite data is persisted after application close and even phone switch off.

Does ALTER TABLE work in SQLite?

Overview. SQLite supports a limited subset of ALTER TABLE. The ALTER TABLE command in SQLite allows these alterations of an existing table: it can be renamed; a column can be renamed; a column can be added to it; or a column can be dropped from it.

How do I add multiple columns in SQLite?

SQLite does not support adding multiple columns to a table using a single statement. To add multiple columns to a table, you must execute multiple ALTER TABLE ADD COLUMN statements.


2 Answers

Please see this page for the syntax to create a new column on a table. Basically it is:

ALTER TABLE mytable ADD COLUMN mycolumn TEXT 

In your onUpgrade method, it would look something like this:

@Override public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {     String upgradeQuery = "ALTER TABLE mytable ADD COLUMN mycolumn TEXT";     if (oldVersion == 1 && newVersion == 2)          db.execSQL(upgradeQuery); } 
like image 186
Jack Avatar answered Oct 14 '22 03:10

Jack


A better approach

@Override public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {     switch (oldVersion) {         case 1:             db.execSQL(SQL_MY_TABLE);           case 2:             db.execSQL("ALTER TABLE myTable ADD COLUMN myNewColumn TEXT");      } } 

Lets say in case 1, you upgraded to db version 2. You created a new table but forgot the myNewColumn you will see in case 2. What this will do is if you change the db version to 3, case 2 will get ran if its upgrading from 2 to 3.

like image 31
Codeversed Avatar answered Oct 14 '22 02:10

Codeversed