Вопрос

Это onUpgrade метод SQLiteOpenHelper когда-нибудь звонил?Если да, то когда он вызывается и чем?Если он не вызывается разработчиками, то почему он там?Что на самом деле происходит с этой функцией?Я видел примеры, когда он удалял все таблицы, но затем в комментарии говорилось, что удаление всех таблиц — это не то, что вам следует делать.Какие-либо предложения?

Это было полезно?

Решение

Это называется при создании SQLiteopenheelper с версией новее, чем версия открытой базы данных. Что делать, зависит от изменений в базе данных, выполненных между старыми и новыми версиями. Единственный случай, когда вы не бросаете измененную таблицу, заключается в том, когда изменение является изменением более чем дополнительной колонны. Затем вы можете использовать оператор ALTER TABLE, чтобы добавить новый столбец к подписи таблицы.

Другие советы

Для тех из вас, кто хотел бы знать точный момент, когда onUpgrade() звонят, это происходит во время звонка либо getReadableDatabase() или getWriteableDatabase().

Для тех, кому неясно, как это обеспечивает срабатывание, ответ такой:Он срабатывает, когда версия базы данных предоставляется конструктору SqLiteOpenHelper обновляется.Вот пример

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
}

теперь...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);
}

Если вы используете SQLiteopenheelper, onupgrade будет вызываться всякий раз, когда вы изменяете версию БД. Для этого требуется дополнительное требование. Имя БД должно оставаться прежним.

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

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

В Oncreate поставщика контента вы создаете экземпляр SQLiteopenheelper, который требует следующих параметров. Ваша реализация SQLiteopenHelper будет выглядеть так:

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
        }

}

Рецензируя все сообщения и запустить код отладки, мне все еще не было понятно, когда я увижу, когда он увидит, что onupgrade вызывается. Я начинал думать, что Android был серьезным недостатком ..

Информация на этой странице привела меня к моему окончательному разрешению. Спасибо кучу всем участникам!

Это решило это для меня ...

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...
}

Это правда, что getwritabledabaseabase () и getReadabledabaseabase () делает результат в вызове onupgrade. Я не проверял другие методы, так как они соответствуют законопроекту за мои потребности.

Продолжайте читать, кикер придет ...

Этот код в моей начальной деятельности просветил меня, когда я наконец понял, что версия БД обновляла во время моей отладки ... фу!

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

Примечание. Вызов конструктора DatabaseHelper обновляет версию БД

После звонка конструктора DB была помечена новой версией. Убейте приложение перед вызовом getwritabledatabase () или getReadabledabaseabase (), а вы на новой версии. После этого новые казнения никогда не вызывают метод onupgrade до тех пор, пока не будет увеличена database_version. (вздох! Теперь это кажется смешным очевидным :)

Мое предложение состоит в том, чтобы добавить какую-то «CheckDatabaseversion ()» на ранние этапы вашего приложения. Кроме того, если вы создаете объект SQLiteopenHelper, убедитесь, что вы называете один из методов (getWritabledabase (), getReadabledableabase () и т. Д.) Перед умиранием вашего приложения ..

Я надеюсь, что это спасает кого-то еще ту же голову, царапаясь! ...: P

Глядя в SqliteOpenHelper Исходный код, мы можем знать onCreate(),onUpgrade() а также onDowngrade вызвать getWritableDatabase() или getReadableDatabase() метод.

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

это на самом деле называется Когда вы называете getReadableDatabase или getWritableDatabase.

Глубокое погружение:

Вы проходите номер версии в конструкторе SQLiteOpenHelper который хранится в переменной вызывается mNewVersion. Отказ Вот и все. В этот момент ничего не происходит.

Каждый раз, когда вы называете GETREADBALDALDATABASE или GETWRITALDATHATABASE, он будет вызывать метод под названием getDatabaseLocked. Отказ Этот метод получит существующую версию номер базы данных и сравнивает его с mNewVersion.

  1. Если база данных с указанным именем не существует, это позвонит onCreate
  2. Если новая версия больше, чем старая версия, она позвонит onUpgrade.
  3. Если новая версия ниже существующей версии, будет брошена исключение.
  4. Если они равны, это будет идти вперед и откройте базу данных.

Что я должен писать в oncreate и Onupgrade?

onCreate должен содержать код, который создает схему в первый раз.

Ты можешь уйти onUpgrade Пустой первый раз, поскольку он не будет вызван в первый раз. Когда вы хотите изменить структуру таблицы на более позднем этапе, этот код должен идти здесь.

Sqliteopenheelper.java(Исходный код)

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);
 }
Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top