Alguna vez se llama el método ONUPGRADE?

votos
33

Es el onUpgrademétodo de SQLiteOpenHelpersiempre llama? Si es así, cuando se le llama y por qué? Si no es llamado por los desarrolladores, entonces por qué está ahí? Lo que realmente sucede con esa función? He visto ejemplos en los que las gotas todas las tablas, pero luego un comentario dice que el abandono de todas las tablas no es lo que debe hacer. ¿Alguna sugerencia?

Publicado el 02/07/2010 a las 06:07
fuente por usuario
En otros idiomas...                            


6 respuestas

votos
21

Se llama cuando se construye un SQLiteOpenHelper con la versión más reciente que la versión de la base de datos abierta. Lo que debe hacer depende de los cambios en la base de datos que se realizan entre las viejas y las nuevas versiones. El único caso en el que no borra una tabla cambiado es cuando el cambio está observando más de una columna añadido. A continuación, puede utilizar la instrucción ALTER TABLE para añadir la nueva columna a la tabla de la firma.

Respondida el 02/07/2010 a las 06:17
fuente por usuario

votos
28

si su están utilizando la SQLiteOpenHelper la ONUPGRADE será llamado cada vez que cambie la versión DB. Hay un requisito adicional para que esto funcione. El nombre db tiene que seguir siendo el mismo.

Old Version:
dbName = "mydb.db"
dbVersion = 1

New Version:
dbName = "mydb.db"
dbVersion = 2

en el onCreate del proveedor de contenido se crea una instancia de la SQLiteOpenHelper que toma estos parametros. Su aplicación SQLiteOpenHelper se vería así:

public static final class MySQLiteOpenHelper extends SQLiteOpenHelper {

        public MySQLiteOpenHelper(Context context, int dbVersion, String dbName) {
            super(context, dbName, null, dbVersion);
        }

        @Override
        public void onCreate(SQLiteDatabase db) {
            //Code to create your db here
        }

        @Override
        public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
            // Code to upgrade your db here
        }

}
Respondida el 12/04/2011 a las 19:29
fuente por usuario

votos
36

Para aquellos de ustedes que le gustaría saber el momento exacto en que onUpgrade()se vuelve a llamar, es durante una llamada a cualquiera getReadableDatabase()o getWriteableDatabase().

Para aquellos que no están claro cómo asegurar que se desencadena, la respuesta es: Se activa cuando la versión de la base de datos proporcionada al constructor SqLiteOpenHelperse actualiza. Aquí es un ejemplo

public class dbSchemaHelper extends SQLiteOpenHelper {

private String sql;
private final String D_TAG = "FundExpense";
//update this to get onUpgrade() method of sqliteopenhelper class called
static final int DB_VERSION = 2; 
static final String DB_NAME = "fundExpenseManager";

public dbSchemaHelper(Context context) {
    super(context, DB_NAME, null, DB_VERSION);
    // TODO Auto-generated constructor stub
}

Ahora ... a ONUPGRADE ()

@Override
public void onUpgrade(SQLiteDatabase arg0, int arg1, int arg2) {
    sql = "ALTER TABLE " + fundExpenseSchema.Expense.TABLE_NAME + " ADD COLUMN " + fundExpenseSchema.Expense.FUNDID + " INTEGER";
    arg0.execSQL(sql);
}
Respondida el 23/12/2011 a las 22:16
fuente por usuario

votos
4

Revisar todos los mensajes y la ejecución de código de depuración que todavía no estaba claro para mí cuando veía ONUPGRADE recibiendo llamadas. Estaba empezando a pensar que Android tenía un grave defecto ..

La información en esta página me llevó a mi resolución final. Muchísimas gracias a todos los colaboradores

Esto resolvió por mí ...

public class DatabaseHelper extends SQLiteOpenHelper {
    public static String TAG = DatabaseHelper.class.getName();
    private static final int DATABASE_VERSION = 42;
    private static final String DATABASE_NAME = "app_database";
    private static final String OLD_TABLE = "old_and_useless";

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

    @Override
    public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion ) {
        if( newVersion > oldVersion) {
            Log.d( TAG, "cool! you noticed." );

            db.execSQL( "DROP TABLE IF EXISTS " + OLD_TABLE );
            // other calls like onCreate if necessary

        } else {
            Log.d( TAG, "Hey! didn't you see me?" );
        }

    }

    public void checkDatabaseVersion() {
        SQLiteDatabase db = this.getWritableDatabase();

        // if the DATABASE_VERSION is newer
        //    onUpgrade is called before this is reached
    }


    // other code removed for readability...
}

Es cierto que getWritableDatabase () y getReadableDatabase () da lugar a la llamada ONUPGRADE. No vi otros métodos, ya que estos se ajustaba perfectamente a mis necesidades.

Sigue leyendo, el truco está llegando ...

Este código en mi actividad inicial me iluminó cuando finalmente me di cuenta de que la versión del DB fue la actualización de depuración durante mi ... uf!

DatabaseHelper dbHelper = new DatabaseHelper( this );
dbHelper.checkDatabaseVersion();

NOTA: llamando al constructor DatabaseHelper actualiza la versión db

Después de la llamada al constructor, el PP fue etiquetado con la nueva versión. Matar a la aplicación antes de una llamada a getWritableDatabase () o getReadableDatabase () y ya está en la nueva versión. A partir de entonces nuevas ejecuciones no llaman al método ONUPGRADE hasta Database_Version se aumenta de nuevo. ( Suspiro! Ahora parece ridículamente obvio :)

Mi sugerencia es añadir algún tipo de "checkDatabaseVersion ()" para las primeras etapas de su aplicación. Alternativamente, si se crea un objeto SQLiteOpenHelper asegúrese de llamar a uno de los métodos (getWritableDatabase (), getReadableDatabase (), etc.) antes de su aplicación muere ..

Espero que esto ahorra otra persona del mismo rascarse la cabeza ...: p

Respondida el 30/05/2015 a las 05:12
fuente por usuario

votos
2

Mirando en el SqliteOpenHelpercódigo fuente, podemos saber onCreate(), onUpgrade()y onDowngradeser llamado en getWritableDatabase()o getReadableDatabase()método.

public SQLiteDatabase getWritableDatabase() {
    synchronized (this) {
        return getDatabaseLocked(true);
    }
}
public SQLiteDatabase getReadableDatabase() {
    synchronized (this) {
        return getDatabaseLocked(false);
    }
}

private SQLiteDatabase getDatabaseLocked(boolean writable) {
    if (mDatabase != null) {
        if (!mDatabase.isOpen()) {
            // Darn!  The user closed the database by calling mDatabase.close().
            mDatabase = null;
        } else if (!writable || !mDatabase.isReadOnly()) {
            // The database is already open for business.
            return mDatabase;
        }
    }
          . . . . . .  

        final int version = db.getVersion();
        if (version != mNewVersion) {
            if (db.isReadOnly()) {
                throw new SQLiteException("Can't upgrade read-only database from version " +
                        db.getVersion() + " to " + mNewVersion + ": " + mName);
            }

            db.beginTransaction();
            try {
                if (version == 0) {
                    onCreate(db);
                } else {
                    if (version > mNewVersion) {
                        onDowngrade(db, version, mNewVersion);
                    } else {
                        onUpgrade(db, version, mNewVersion);
                    }
                }
                db.setVersion(mNewVersion);
                db.setTransactionSuccessful();
            } finally {
                db.endTransaction();
            }
        }

        onOpen(db);

        if (db.isReadOnly()) {
            Log.w(TAG, "Opened " + mName + " in read-only mode");
        }

        mDatabase = db;
        return db;
    } finally {
        mIsInitializing = false;
        if (db != null && db != mDatabase) {
            db.close();
        }
    }
}
Respondida el 20/10/2015 a las 00:24
fuente por usuario

votos
1

Se llama en realidad cuando llame getReadableDatabaseo getWritableDatabase.

Bucear profundo:

Se pasa el número de versión en el constructor de la SQLiteOpenHelperque se almacena en una variable llamada mNewVersion. Eso es. No pasa nada en este momento.

Cada vez que se llama a getReadableDatabase o getWritableDatabase, se llamará a un método llamado getDatabaseLocked. Este método va a obtener el número de versión existente de la base de datos y compararlo con el mNewVersion.

  1. Si no existe la base de datos con el nombre dado se llamará onCreate
  2. Si la nueva versión es mayor que la vieja versión se llamará onUpgrade.
  3. Si la nueva versión es inferior a la versión existente, se produce una excepción.
  4. Si son iguales que seguirá adelante y abrir la base de datos.

¿Qué debo escribir en onCreate y ONUPGRADE?

onCreate debe contener el código que crea un esquema para la primera vez.

Puede dejar onUpgradevacíos primera vez, ya que no se llamará la primera vez. Cuando se desea cambiar la estructura de la tabla en una fase posterior, que el código debe ir aquí.

SQLiteOpenHelper.java (código fuente)

public SQLiteDatabase getWritableDatabase() {
    synchronized (this) {
        return getDatabaseLocked(true);
    }
}

 public SQLiteDatabase getReadableDatabase() {
    synchronized (this) {
        return getDatabaseLocked(false);
    }
}

private SQLiteDatabase getDatabaseLocked(boolean writable) {
   .
   .

     final int version = db.getVersion();

        if (version != mNewVersion) {
            if (db.isReadOnly()) {
                throw new SQLiteException("Can't upgrade read-only database from version " +
                        db.getVersion() + " to " + mNewVersion + ": " + mName);
            }

            db.beginTransaction();
            try {
                if (version == 0) {
                    onCreate(db);
                } else {
                    if (version > mNewVersion) {
                        onDowngrade(db, version, mNewVersion);
                    } else {
                        onUpgrade(db, version, mNewVersion);
                    }
                }
                db.setVersion(mNewVersion);
                db.setTransactionSuccessful();
            } finally {
                db.endTransaction();
            }
       }

       onOpen(db);
 }
Respondida el 21/06/2017 a las 03:59
fuente por usuario

Cookies help us deliver our services. By using our services, you agree to our use of cookies. Learn more