2011-10-01 13 views
27

Tengo una base de datos con 4 columnas:SQLite agregar la columna, mantener los datos

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

Ahora quiero añadir otra columna, pero mantener las filas que ya están en la base de datos. ¿Cómo debería hacer esto? No puedo encontrar ninguna referencia útil a esto.

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

EDITAR

he modificado mi onCreate a:

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

y mi ONUPGRADE a:

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

Sin embargo, ahora me sale este 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 

Respuesta

48

favor ver this página para la sintaxis para crear una nueva columna en una tabla. Básicamente se trata de:

ALTER TABLE mytable ADD COLUMN mycolumn TEXT 

En el método de ONUPGRADE, se vería algo como esto:

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

Por favor, vea mi edición – nhaarman

+1

¿Por qué llama a onCreate() después? La actualización implica que ya se ha llamado a onCreate() (lo que significa que las tablas/db ya están creadas). El problema se detalla en la excepción (incluso hasta el número de línea - Línea 25 en onCreate()). Está intentando crear una tabla que ya existe. – Jack

+0

Ah, está bien. Pero tengo la línea donde elimino el db después de la actualización de la versión 1, ¿necesito llamar a onCreate entonces? – nhaarman

2

no he trabajado con Android, pero SQLite ofrece 'alter table' como la mayoría de las implementaciones de SQL hace:

SQLite alter table

+0

ALTER TABLE MyTable ADD COLUMN MyNewCol TEXT; –

6

Un mejor enfoque

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

    } 
} 

digamos que en el caso 1, se ha actualizado a la versión 2 de db. Usted creó una nueva tabla pero olvidó myNewColumn que verá en el caso 2. Lo que esto hará es si cambia la versión de db a 3, caso 2 se ejecutará si es actualización de 2 a 3.

+0

En la versión 3 no es el caso segunda consulta, redundante querys en el caso 3. –

+0

Esto en onUpgrade que muestra cuando la versión anterior es la versión 2 por lo que la nueva versión sería la versión 3 y se ejecutaría el código. Este código es correcto y funciona. – Codeversed

+2

El único problema que veo con este código es que debe eliminar todos los saltos de la declaración de cambio (y asegúrese de que todos los casos estén en orden ascendente), para que también se ejecuten todos los casos debajo del caso OldVersion. – TheIT

Cuestiones relacionadas