>

Udacity에서 Android 앱 개발을 배우고 있으며, 데이터베이스 스키마를 변경할 때 DATABASE_VERSION을 변경해야한다고 지시하는 데이터베이스 과정을 수강했습니다. 그것은 나를 많이 혼란 시켰지만 해결책을 찾지 못했습니다. 누군가 제게 설명해주세요.

감사합니다

  • 답변 # 1

    이 시나리오를 상상해보십시오 :

    <올>

    앱의 초기 버전을 만들었습니다.

    사람들이 앱을 설치했고 데이터베이스를 처음 사용할 때 onCreate() 방법  Android가 실행되고 내부 메모리에 데이터베이스가 생성되었습니다 (예 : test.db).

    이제 새 열이 필요한 새 기능을 만들었습니다 (스키마를 변경했습니다).

    onCreate 때문에 새로운 버전의 앱을 설치할 새로운 사용자는 괜찮을 것입니다  이 새로운 열로 실행됩니다.

    그러나 이미 데이터베이스를 파일 시스템에서 만든 기존 사용자는 어떻습니까?

    그 때문에 데이터베이스를 업데이트하기위한 메커니즘이 필요합니다. 앱의 새 버전에서는 새 데이터베이스 스키마에 대한 SQL 쿼리가 있습니다. 새 열을 사용하는 쿼리가 있습니다. 그러나 이전 사용자에게는 여전히 이전 버전의 데이터베이스가 있습니다. 새 열은 아직 존재하지 않습니다.

    업데이트 메커니즘은 간단합니다. 데이터베이스를 업그레이드 할 때마다 데이터베이스 버전을 높이십시오. Android는 파일 시스템에서 데이터베이스 버전을 자동으로 확인합니다. 설치된 버전이 현재 데이터베이스보다 오래된 경우 onUpdate()  호출되면 원하는 방식으로 업데이트 할 수 있습니다.

    이전 테이블을 삭제하고 새 테이블을 만들면됩니다.

    이전 데이터를 삭제하지 않고 새 열을 만들 수 있습니다.

    기타 ... 프로젝트마다 다릅니다. 필요에 따라 다릅니다. 예를 들어 결코 사용하지 않았을 수 있습니다.

    아직 APK를 출시하지 않은 경우 아직 아무도 앱을 설치하지 않았기 때문에 데이터베이스 버전을 변경할 필요가 없습니다. 필요한 변경을 계속하십시오. 그러나 앱이 출시 된 후에는 항상 데이터베이스 버전과 업데이트 방법에 대해 특별한주의를 기울여야합니다 ... 항상 새로 설치하여 테스트를 시뮬레이션하고 앱을 업데이트하는 사용자를 시뮬레이션해야합니다 ...

  • 답변 # 2

    Why is it necessary to update the VERSION NUMBER of database when adding a new column in schema?

    버전 번호를 업데이트 할 필요는 없으며,사용자 버전필드에 저장된 값과 비교하여 코드에 제공된 버전 번호를 확인하여 구조적 변경 사항을 도입하는 것이 좋습니다. 데이터베이스 파일 헤더 (오프셋 60에서 4 바이트)의 유일한 방법은 아닙니다. 편리합니다.

    SQLiteOpenHelper 클래스의 서브 클래스 (확장)를 사용하는 경우에만 적용 가능합니다. SQLiteDatabase openDatabase 메소드 (이 경우onCreate또는onUpgrade중 하나 (또는 ​​거의 사용되지 않는)를 사용할 수 있으므로 이러한 서브 클래스를 사용할 필요가 없습니다. >onDowngrade) 메소드가 호출되거나 사용 가능합니다).

    일부 작업으로sqlite_master테이블을 통해 구조를 확인/비교하는 프로세스 및 스키마에 대한 pragma와 같은 대안을 구현할 수 있습니다. 테이블을 사용하여 구조적 변경 사항을 추적하는 프로세스를 구현할 수 있습니다. 데이터베이스가 비어 있으면 디스크 공간을 낭비 할 수 있지만 모델로 사용할 수 있습니다.

    예를 들어, 열 추가를 기반으로 테이블과 열 정의가 제공되는 메소드를 가질 수 있으며 열이 테이블에 존재하는지 확인합니다 (예 : PRAGMA table_info 의 결과를 검사하여) )이 아닌 경우ALTERations를 적용합니다.

    일반적으로 혼란은onUpgrade방법이 아니라onCreate방법에 대한 오해입니다. 즉, 앱을 실행할 때마다onCreate메소드가 실행되지 않으며,onCreate메소드는 데이터베이스가 생성 될 때만 자동으로 실행됩니다. (이 경우 다시 실행됩니다).

    혼동은 값을 초기화/설정하는 데 사용되는 활동에서onCreate방법을 자주 보는 사람들로부터 비롯 될 수 있습니다.

    이러한 앱에서는onCreate가 실행되지 않기 때문에 구조적 변경을 도입하는 수단이 필요할 수 있습니다 (예 : 일반적으로 사용되는onCreate메소드와 같은onUpgrade방법)

    데모

    기본 앱으로 작동하는 코드는 데이터베이스 구조를 변경합니다 앱이 실행될 때마다 여러 릴리스를 시뮬레이션합니다 (처음 4 실행하면 구조가 안정됩니다).

    실제 앱에서 사용하기위한 것이 아닙니다.

    대부분의 구조 변경은onUpgrade를 통해 수행되지 않습니다. 방법. 그러나 네 번째 실행은 구조를 변경합니다 ( onUpgrade방법

    을 통해

    데이터베이스 헬퍼 (SQLiteOpenHelper의 서브 클래스) :-

    public class TestDBHelper extends SQLiteOpenHelper {
        public static final String DBNAME = "testdb";
        public static final String TBNAME_001 = "test001_table";
        public static final String TBNAME_002 = "test002_table";
        public static final String TBNAME_003 = "test003_table";
        public static final String COL_NAME = "name_column";
        public static final String COL_EXTRA = "extra_cxolumn";
        String TAG = "TESTDBHLPR";
        public TestDBHelper(Context context) {
            //<<<<<<<<<<Note gets database version according to value in MainActivity>>>>>>>>>>
            super(context, DBNAME, null, MainActivity.getDatabaseVersion());
            Log.d(TAG,"CONSTRUCTOR invoked.");
            this.getWritableDatabase(); //<<<<< Force  database open
        }
        @Override
        public void onCreate(SQLiteDatabase db) {
            Log.d(TAG,"ONCREATE invoked.");
        }
        @Override
        public void onUpgrade(SQLiteDatabase db, int old_version, int new_version) {
            Log.d(TAG,"ONUPGRADE invoked. " +
                    "\n\tOld version (valued stored in DB) is " + String.valueOf(old_version) +
                    "\n\tNew version (as coded in the App) is " + String.valueOf(new_version)
            );
            if (new_version == 2) {
                db.execSQL(getAlterSQl(TBNAME_003));
            }
        }
        public static String getAlterSQl(String table_name) {
            return "ALTER TABLE " + table_name + " ADD COLUMN " + COL_EXTRA + " TEXT";
        }
    }
    
    

    onCreate는 로그에 출력을 쓰는 것 외에는 아무것도하지 않습니다.

    앱이 실행될 때마다 테이블이 점진적으로 추가됩니다.

    onUpgrade는 버전 번호가 2로 변경된 경우에만 작동합니다.

    getAlterSQL 메소드는 단순히 문자열ALTER TABLE ????? 칼럼 추가 텍스트 추가

    MainActivity에서 데이터베이스 버전을 가져 오는 방법에 유의하십시오 (시연을 위해 버전을 즉시 변경할 수 있음).

    다음은 호출 활동MainActivity.java

    의 코드입니다.
    public class MainActivity extends AppCompatActivity {
        TestDBHelper mDBHlpr; //<<<<<<<<<< Declare the Database Helper (will at this stage be NULL)
        Context mContext;
        static int mDatabaseVersion = 1; //<<<<<<<<<< DBVERSION can be changed on the fly
        String TAG = "MAINACTIVITY";
        @Override
            protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_main);
            mContext = this;
            addNewTable(); //<<<<<<<<<< update database structure if needed
            Log.d(TAG,"Instantiating the Database helper");
            mDBHlpr = new TestDBHelper(this);
            logDBInfo(mDBHlpr.getWritableDatabase());
        }
        public static int getDatabaseVersion() {
            return mDatabaseVersion;
        }
        private void addNewTable() {
            String TAG = "ADDNEWTABLE";
            File db_file = this.getDatabasePath(TestDBHelper.DBNAME);
            if (!db_file.exists()) {
                Log.d(TAG,"Database doesn't exist so exiting.");
                return;
            }
            Log.d(TAG,"Database file exists. Checking for table");
            SQLiteDatabase db = SQLiteDatabase.openDatabase(
                    this.getDatabasePath(TestDBHelper.DBNAME).getPath(),
                    null,
                    SQLiteDatabase.OPEN_READWRITE,
                    null
            );
            Log.d(TAG,"Writing Database info (if any) as before any changes");
            logDBInfo(db);
            Log.d(TAG,"Database existed and has been opened");
            String whereclause = "type='table' AND tbl_name LIKE 'test%'";
            Cursor csr = db.query("sqlite_master",null,whereclause,null,null,null,null);
            int row_count = csr.getCount();
            Log.d(TAG,"Extracted " + String.valueOf(row_count) + " application tables");
            csr.close();
            String table_name = "x"; //<<<<<
            switch (row_count) {
                case 0:
                    table_name = TestDBHelper.TBNAME_001;
                    break;
                case 1:
                    table_name = TestDBHelper.TBNAME_002;
                    Log.d(TAG,"Adding column " + TestDBHelper.COL_EXTRA + " to table " + TestDBHelper.TBNAME_001);
                    db.execSQL(TestDBHelper.getAlterSQl(TestDBHelper.TBNAME_001));
                    break;
                case 2:
                    table_name = TestDBHelper.TBNAME_003;
                    mDatabaseVersion = 2; //<<<<<<<<<< Force onUpgrade
                    break;
                default:
                    mDatabaseVersion = 2;
            }
            if (table_name.length() < 2) {
                Log.d(TAG,"Database exists but nothing to do");
                return;
            }
            Log.d(TAG,"Creating table " + table_name);
            String crt_sql = "CREATE TABLE IF NOT EXISTS " + table_name + "(" +
                    TestDBHelper.COL_NAME + " TEXT" +
                    ")";
            db.execSQL(crt_sql);
            Log.d(TAG,"Writing Database info (if any) as after any changes");
            logDBInfo(db);
            db.close();
        }
        private void logDBInfo(SQLiteDatabase db) {
            String TAG = "DBINFO";
            Cursor csr = db.query("sqlite_master",null,null,null,null,null,null);
            while (csr.moveToNext()) {
                String type = csr.getString(csr.getColumnIndex("type"));
                String table_name = csr.getString(csr.getColumnIndex("tbl_name"));
                Log.d(TAG,"Type is " + type + " for table " + table_name);
                if (type.equals("table")) {
                    Cursor csr2 = db.rawQuery("PRAGMA table_info(" + table_name + ")",null);
                    while (csr2.moveToNext()) {
                        Log.d(TAG,"\n\tTable has a column named " + csr.getString(csr2.getColumnIndex("name")));
                    }
                    csr2.close();
                }
            }
            csr.close();
        }
    }
    
    

    데이터베이스 헬퍼를 인스턴스화하기 전에 앱을 실행하면addNewTable메소드가 실행됩니다.

    addNewTable메소드는 데이터베이스에있는 내용에 따라 다른 작업을 수행합니다.

    처음 실행

    앱이 처음으로 실행 된 경우 (또는 데이터베이스가 삭제/앱 제거 된 경우) 메소드는 단순히 반환합니다.

    데이터베이스 헬퍼가 인스턴스화 될 때 데이터베이스가 생성된다 ( this.getWritableDatabase(); //<<<<< Force database open 에 의해) ).

    onCreate메소드가 호출 되었으나 구조적으로는 아무 것도하지 않습니다.

    마지막으로 logDBInfo 메소드가 호출되어 테이블을 나열합니다 (데이터베이스가 작성 될 때android_metadata테이블이 작성되므로이 목록이 표시됩니다. 이는 로케일이 포함 된 Android 특정 테이블이며 일반적으로 무시 됨).

    로그에 약간의 로깅이 추가되어 다음과 같이 표시됩니다 :-

    11-02 18:45:02.689 2066-2066/axtest.axtest D/ADDNEWTABLE: Database doesn't exist so exiting.
    11-02 18:45:02.689 2066-2066/axtest.axtest D/MAINACTIVITY: Instantiating the Database helper
    11-02 18:45:02.689 2066-2066/axtest.axtest D/TESTDBHLPR: CONSTRUCTOR invoked.
    11-02 18:45:02.701 2066-2066/axtest.axtest D/TESTDBHLPR: ONCREATE invoked.
    11-02 18:45:02.701 2066-2066/axtest.axtest D/DBINFO: Type is table for table android_metadata
    11-02 18:45:02.701 2066-2066/axtest.axtest D/DBINFO:    Table has a column named locale
    
    
    두 번째 실행

    addNewTable이 호출 될 때 데이터베이스가 존재하므로 반환되지 않고 대신 데이터베이스를 열고 (데이터베이스 도우미를 사용하지 않음) 데이터베이스 정보를 기록합니다 ( 변경 사항이 적용되기 전에)

    그런 다음sqlite_master테이블 (항목에 대한 데이터가있는 SQLite 내부/시스템 테이블)에서 쿼리를 실행하고test로 시작하는 테이블의 행을 추출합니다 ( 존재하는 유일한 테이블이sqlite_masterandroid_metadata)이므로 아무도 없어야합니다.

    테이블 수와 같은 행 수를 얻습니다. 두 번째 런은 0입니다.

    스위치/케이스는 이에 따라 테이블 이름을 설정합니다.이 실행에 대해 상수TABLE001에 의해 유지되는 값 (결과 값의 길이가 1보다 큼)으로 설정 한 다음 표.

    테이블이 생성 된 후 데이터베이스 정보가 기록되어 이제 새 테이블이 표시되고 데이터베이스가 닫힙니다.

    데이터베이스 헬퍼가 인스턴스화되고onCreate는 데이터베이스가 현재 존재하므로 호출되지 않으며onUpgrade는 버전이 1이므로 호출되지 않습니다. 마지막으로 데이터베이스 정보는 다음과 같습니다. 기록되었습니다.

    로그는 :-

    11-02 18:46:16.009 2109-2109/axtest.axtest D/ADDNEWTABLE: Database file exists. Checking for table
    11-02 18:46:16.013 2109-2109/axtest.axtest D/ADDNEWTABLE: Writing Database info (if any) as before any changes
    11-02 18:46:16.013 2109-2109/axtest.axtest D/DBINFO: Type is table for table android_metadata
    11-02 18:46:16.013 2109-2109/axtest.axtest D/DBINFO:    Table has a column named locale
    11-02 18:46:16.013 2109-2109/axtest.axtest D/ADDNEWTABLE: Database existed and has been opened
    11-02 18:46:16.013 2109-2109/axtest.axtest D/ADDNEWTABLE: Extracted 0 application tables
    11-02 18:46:16.013 2109-2109/axtest.axtest D/ADDNEWTABLE: Creating table test001_table
    11-02 18:46:16.021 2109-2109/axtest.axtest D/ADDNEWTABLE: Writing Database info (if any) as after any changes
    11-02 18:46:16.021 2109-2109/axtest.axtest D/DBINFO: Type is table for table android_metadata
    11-02 18:46:16.021 2109-2109/axtest.axtest D/DBINFO:    Table has a column named locale
    11-02 18:46:16.021 2109-2109/axtest.axtest D/DBINFO: Type is table for table test001_table
    11-02 18:46:16.021 2109-2109/axtest.axtest D/DBINFO:    Table has a column named name_column
    11-02 18:46:16.021 2109-2109/axtest.axtest D/MAINACTIVITY: Instantiating the Database helper
    11-02 18:46:16.021 2109-2109/axtest.axtest D/TESTDBHLPR: CONSTRUCTOR invoked.
    11-02 18:46:16.021 2109-2109/axtest.axtest D/DBINFO: Type is table for table android_metadata
    11-02 18:46:16.021 2109-2109/axtest.axtest D/DBINFO:    Table has a column named locale
    11-02 18:46:16.021 2109-2109/axtest.axtest D/DBINFO: Type is table for table test001_table
    11-02 18:46:16.021 2109-2109/axtest.axtest D/DBINFO:    Table has a column named name_column
    
    
    세번째 달리기

    이것은 test001_table 대신test002_table이 추가되고tes001_table테이블에열이 추가 된 것 이외의 두 번째 실행과 유사합니다.>이름이extra_column입니다.

    로그는 :-

    11-02 18:50:13.925 2160-2160/axtest.axtest D/ADDNEWTABLE: Database file exists. Checking for table
    11-02 18:50:13.929 2160-2160/axtest.axtest D/ADDNEWTABLE: Writing Database info (if any) as before any changes
    11-02 18:50:13.933 2160-2160/axtest.axtest D/DBINFO: Type is table for table android_metadata
    11-02 18:50:13.933 2160-2160/axtest.axtest D/DBINFO:    Table has a column named locale
    11-02 18:50:13.933 2160-2160/axtest.axtest D/DBINFO: Type is table for table test001_table
    11-02 18:50:13.933 2160-2160/axtest.axtest D/DBINFO:    Table has a column named name_column
    11-02 18:50:13.933 2160-2160/axtest.axtest D/ADDNEWTABLE: Database existed and has been opened
    11-02 18:50:13.933 2160-2160/axtest.axtest D/ADDNEWTABLE: Extracted 1 application tables
    11-02 18:50:13.937 2160-2160/axtest.axtest D/ADDNEWTABLE: Adding column extra_column to table test001_table
    11-02 18:50:13.937 2160-2160/axtest.axtest D/ADDNEWTABLE: Creating table test002_table
    11-02 18:50:13.941 2160-2160/axtest.axtest D/ADDNEWTABLE: Writing Database info (if any) as after any changes
    11-02 18:50:13.941 2160-2160/axtest.axtest D/DBINFO: Type is table for table android_metadata
    11-02 18:50:13.941 2160-2160/axtest.axtest D/DBINFO:    Table has a column named locale
    11-02 18:50:13.941 2160-2160/axtest.axtest D/DBINFO: Type is table for table test001_table
    11-02 18:50:13.941 2160-2160/axtest.axtest D/DBINFO:    Table has a column named name_column
    11-02 18:50:13.941 2160-2160/axtest.axtest D/DBINFO:    Table has a column named extra_column
    11-02 18:50:13.941 2160-2160/axtest.axtest D/DBINFO: Type is table for table test002_table
    11-02 18:50:13.941 2160-2160/axtest.axtest D/DBINFO:    Table has a column named name_column
    11-02 18:50:13.941 2160-2160/axtest.axtest D/MAINACTIVITY: Instantiating the Database helper
    11-02 18:50:13.941 2160-2160/axtest.axtest D/TESTDBHLPR: CONSTRUCTOR invoked.
    11-02 18:50:13.945 2160-2160/axtest.axtest D/DBINFO: Type is table for table android_metadata
    11-02 18:50:13.945 2160-2160/axtest.axtest D/DBINFO:    Table has a column named locale
    11-02 18:50:13.945 2160-2160/axtest.axtest D/DBINFO: Type is table for table test001_table
    11-02 18:50:13.945 2160-2160/axtest.axtest D/DBINFO:    Table has a column named name_column
    11-02 18:50:13.945 2160-2160/axtest.axtest D/DBINFO:    Table has a column named extra_column
    11-02 18:50:13.945 2160-2160/axtest.axtest D/DBINFO: Type is table for table test002_table
    11-02 18:50:13.945 2160-2160/axtest.axtest D/DBINFO:    Table has a column named name_column
    
    
    제 4 회

    4 번째 실행은test003_table이라는 다른 테이블을 추가하지만 이제 데이터베이스 도우미가 인스턴스화되기 전에 데이터베이스 버전을 1에서 2로 변경하여 결국onUpGrade메소드가 발생합니다. 이 경우extra_column

    열을 추가하여test003_table을 변경합니다.

    로그는 :-

    11-02 18:57:00.589 2230-2230/? D/ADDNEWTABLE: Database file exists. Checking for table
    11-02 18:57:00.593 2230-2230/? D/ADDNEWTABLE: Writing Database info (if any) as before any changes
    11-02 18:57:00.593 2230-2230/? D/DBINFO: Type is table for table android_metadata
    11-02 18:57:00.593 2230-2230/? D/DBINFO:    Table has a column named locale
    11-02 18:57:00.593 2230-2230/? D/DBINFO: Type is table for table test001_table
    11-02 18:57:00.593 2230-2230/? D/DBINFO:    Table has a column named name_column
    11-02 18:57:00.593 2230-2230/? D/DBINFO:    Table has a column named extra_column
    11-02 18:57:00.593 2230-2230/? D/DBINFO: Type is table for table test002_table
    11-02 18:57:00.593 2230-2230/? D/DBINFO:    Table has a column named name_column
    11-02 18:57:00.593 2230-2230/? D/ADDNEWTABLE: Database existed and has been opened
    11-02 18:57:00.593 2230-2230/? D/ADDNEWTABLE: Extracted 2 application tables
    11-02 18:57:00.593 2230-2230/? D/ADDNEWTABLE: Creating table test003_table
    11-02 18:57:00.597 2230-2230/? D/ADDNEWTABLE: Writing Database info (if any) as after any changes
    11-02 18:57:00.597 2230-2230/? D/DBINFO: Type is table for table android_metadata
    11-02 18:57:00.597 2230-2230/? D/DBINFO:    Table has a column named locale
    11-02 18:57:00.597 2230-2230/? D/DBINFO: Type is table for table test001_table
    11-02 18:57:00.597 2230-2230/? D/DBINFO:    Table has a column named name_column
    11-02 18:57:00.597 2230-2230/? D/DBINFO:    Table has a column named extra_column
    11-02 18:57:00.597 2230-2230/? D/DBINFO: Type is table for table test002_table
    11-02 18:57:00.597 2230-2230/? D/DBINFO:    Table has a column named name_column
    11-02 18:57:00.597 2230-2230/? D/DBINFO: Type is table for table test003_table
    11-02 18:57:00.597 2230-2230/? D/DBINFO:    Table has a column named name_column
    11-02 18:57:00.597 2230-2230/? D/MAINACTIVITY: Instantiating the Database helper
    11-02 18:57:00.597 2230-2230/? D/TESTDBHLPR: CONSTRUCTOR invoked.
    11-02 18:57:00.601 2230-2230/? D/TESTDBHLPR: ONUPGRADE invoked. 
            Old version (valued stored in DB) is 1
            New version (as coded in the App) is 2
    11-02 18:57:00.605 2230-2230/? D/DBINFO: Type is table for table android_metadata
    11-02 18:57:00.605 2230-2230/? D/DBINFO:    Table has a column named locale
    11-02 18:57:00.605 2230-2230/? D/DBINFO: Type is table for table test001_table
    11-02 18:57:00.605 2230-2230/? D/DBINFO:    Table has a column named name_column
    11-02 18:57:00.605 2230-2230/? D/DBINFO:    Table has a column named extra_column
    11-02 18:57:00.605 2230-2230/? D/DBINFO: Type is table for table test002_table
    11-02 18:57:00.605 2230-2230/? D/DBINFO:    Table has a column named name_column
    11-02 18:57:00.605 2230-2230/? D/DBINFO: Type is table for table test003_table
    11-02 18:57:00.605 2230-2230/? D/DBINFO:    Table has a column named name_column
    11-02 18:57:00.605 2230-2230/? D/DBINFO:    Table has a column named extra_column
    
    

    이후 실행은 최종 구조와 데이터베이스 버전 2를 사용합니다.

    스위치/케이스 구성의 기본값이 버전을 2로 설정하지 않아 버전 1이 사용 된 경우onDownGrade메소드가 정의되지 않아 실패합니다.

  • 답변 # 3

    기본적으로 Android에서 데이터베이스 스키마를 변경하려면 SQLHelper 클래스의 onUpgrade () 메소드를 호출해야하며 데이터베이스 스키마에 대한 모든 변경을 수행해야합니다. 데이터베이스 버전 번호를 늘리면 시스템에 데이터베이스 스키마 (예 : 새 테이블 열)가 변경되었음을 알리고 SQLHelper 클래스의 OnUpgrade () 메소드가 트리거됩니다.

    다음은 데이터베이스 버전 번호를 사용하는 방법에 대한 예입니다. 현재 데이터베이스 버전이 4라고 가정합니다.

    public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
        if (oldVersion > 1) {
             // the code to upgrade from our initial database to v2
        }
        if (oldVersion > 2) {
             // the code to upgrade from v2 to v3
        }
        if (oldVersion > 3) {
             // the code to upgrade from v3 to v4
        }
    }
    
    

    이제 응용 프로그램을 다시 설치하면 사용자의 현재 db 버전이 3보다 낮 으면 onUpgrade ()가 호출됩니다. 또한 이전 db 버전의 사용자 데이터베이스를 사용하면 아무 것도 사용하지 않고 새 데이터베이스 스키마로 적절히 마이그레이션 할 수 있습니다 예를 들어 테이블에 열을 추가 한 경우 버전을 항상 변경해야합니다.

    단, 새로운 기능 만 테스트하거나 오래된 데이터를 잃어 버릴 염려가없는 경우 onUpgrade ()가 모든 항목을 삭제하고 완전히 새로 불러 온 onCreate ()를 다시 만들도록 강제 할 수도 있습니다.

    그러나 실제 의미는 다음과 같습니다.

      @Override
        public void onUpgrade( SQLiteDatabase database, int oldVersion, int newVersion ) 
        {
          if (oldVersion<2)
             {
             database.execSQL(myQueryAlignment)
             }
        }
    
    

    업데이트를 시뮬레이션하려면 (예 : 스크립트가 작동하는지 확인) 가능 ADV를 사용하여 에뮬레이터에서 데이터베이스를 삭제하고 이전 데이터베이스를 삽입하고 APK를 다시 설치하십시오 ...이 방법으로 (데이터베이스 버전이 새로운 apk에서 증가한 경우) "인공적인"방식으로 onUpdate ()에서 실행됩니다.

관련 자료

  • 이전 angular5 - 각도 부모 구성 요소는 ng-content 자식 구성 요소를 수신합니다
  • 다음 java - `map - : get`이 찾은 값의`optional` 또는`optionalempty ()`를 리턴하는 방법