SQLiteOpenHelper onCreate () / onUpgrade ()는 언제 실행됩니까? 노트: (매주

나는 내 테이블을 SQLiteOpenHelper onCreate()만들었지 만

SQLiteException: no such table

또는

SQLiteException: no such column

오류. 왜?

노트:

(매주 수십 개의 유사한 질문이 요약되어 있습니다. 여기에서 “정식”커뮤니티 위키 질문 / 답변을 제공하려고 시도하면 모든 질문에 대한 올바른 참조가 가능합니다.)



답변

SQLiteOpenHelper onCreate()onUpgrade()데이터베이스가 실제로 호출에 의해, 예를 들어, 열 때 콜백이 호출됩니다 getWritableDatabase(). 데이터베이스 헬퍼 오브젝트 자체가 작성 될 때 데이터베이스가 열리지 않습니다.

SQLiteOpenHelper데이터베이스 파일 버전. 버전 번호는 생성자에int 전달 된 인수 입니다. 데이터베이스 파일에서 버전 번호는에 저장됩니다 .PRAGMA user_version

onCreate()데이터베이스 파일이 존재하지 않고 방금 작성된 경우에만 실행됩니다. onCreate()성공적으로 반환 되면 (예외가 발생하지 않음) 요청 된 버전 번호로 데이터베이스가 생성 된 것으로 간주됩니다. 함의로서, 당신은 잡을 안 SQLException에들 onCreate()자신.

onUpgrade()데이터베이스 파일이 존재하지만 저장된 버전 번호가 생성자에서 요청한 것보다 낮은 경우에만 호출됩니다. 는 onUpgrade()요청 된 버전으로 테이블 스키마를 업데이트해야합니다.

코드 ( onCreate()) 에서 테이블 스키마를 변경할 때 데이터베이스가 업데이트되었는지 확인해야합니다. 두 가지 주요 접근법 :

  1. 이전 데이터베이스 파일을 삭제하여 onCreate()다시 실행하십시오. 설치된 버전을 제어하고 데이터 손실이 문제가되지 않는 개발 시간에 종종 선호됩니다. 데이터베이스 파일을 삭제하는 몇 가지 방법 :

    • 응용 프로그램을 제거하십시오. 응용 프로그램 관리자 또는 adb uninstall your.package.name쉘에서 사용하십시오 .

    • 응용 프로그램 데이터를 지 웁니다. 응용 프로그램 관리자를 사용하십시오.

  2. onUpgrade()호출 되도록 데이터베이스 버전을 늘리십시오. 더 많은 코드가 필요할수록 약간 더 복잡합니다.

    • 데이터 손실이 문제가되지 않는 개발 시간 스키마 업그레이드의 경우 execSQL("DROP TABLE IF EXISTS <tablename>")기존 테이블을 제거 onCreate()하고 데이터베이스를 재생성하기 위해 호출 할 수 있습니다.

    • 릴리스 된 버전의 경우 onUpgrade()사용자가 데이터를 잃지 않도록 데이터 마이그레이션을 구현해야 합니다.


답변

Jaskey의 요청에 따라 여기에 누락 된 포인트를 추가하려면

데이터베이스 버전은 SQLite데이터베이스 파일 내에 저장 됩니다.

catch는 생성자입니다

SQLiteOpenHelper(Context context, String name, SQLiteDatabase.CursorFactory factory, int version)

따라서 데이터베이스 도우미 생성자가 name(두 번째 매개 변수) 로 호출 되면 플랫폼은 데이터베이스가 존재하는지 여부를 확인하고 데이터베이스가 존재하면 데이터베이스 파일 헤더에서 버전 정보를 가져와 올바른 콜백을 트리거합니다.

이전 답변에서 이미 설명했듯이 이름의 데이터베이스가 존재하지 않으면 트리거됩니다 onCreate.

아래 설명은 onUpgrade사례와 함께 사례를 설명합니다 .

예를 들어 첫 번째 버전의 응용 프로그램에는 생성자 전달 버전 이 DatabaseHelper(extending SQLiteOpenHelper) 1이고 버전이 다음과 같은 새 소스 코드로 업그레이드 된 응용 프로그램을 제공 한 2다음 파일이 이미 DatabaseHelper생성되어 플랫폼 트리거 onUpgrade가 발생하면 파일이 이미 존재 하는지 확인합니다. 그러나 버전이 전달한 현재 버전보다 낮습니다.

이제 db 버전으로 응용 프로그램의 세 번째 버전을 제공 할 계획이라고 가정합니다 3(데이터베이스 스키마가 수정 될 때만 db 버전이 증가 함). 이러한 증분 업그레이드에서는 유지 관리하기 쉬운 코드를 위해 각 버전에서 업그레이드 논리를 증분 작성해야합니다.

아래의 의사 코드 예 :

@Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
  switch(oldVersion) {
    case 1:
       //upgrade logic from version 1 to 2
    case 2:
       //upgrade logic from version 2 to 3
    case 3:
       //upgrade logic from version 3 to 4
       break;
    default:
       throw new IllegalStateException(
                "onUpgrade() with unknown oldVersion " + oldVersion);
  }
}

break경우 1및 누락 된 문을 확인하십시오 2. 이것이 증분 업그레이드의 의미입니다.

이전 버전 인 경우 말 2새로운 버전이 4다음 논리에서 데이터베이스를 업그레이드합니다 23다음에4

이전 버전 인 경우 3새로운 버전이 4, 그것은 단지에 대한 업그레이드 논리 실행 3에를4


답변

onCreate()

  1. 데이터베이스를 처음 만들 때 (즉, 데이터베이스가 존재하지 않는 경우) onCreate()전달 된 버전으로 데이터베이스를 만듭니다.
    SQLiteOpenHelper(Context context, String name, SQLiteDatabase.CursorFactory factory, int version)

  2. onCreate()메소드는 정의한 테이블을 작성하고 작성한 다른 코드를 실행하는 것입니다. 그러나이 메서드는 앱의 데이터 디렉토리 ( /data/data/your.apps.classpath/databases) 에 SQLite 파일이없는 경우에만 호출됩니다 .

  3. 코드를 변경하고 에뮬레이터에서 다시 시작한 경우에는이 메소드가 호출되지 않습니다. 당신이 원하는 경우 onCreate()실행할 수는 SQLite 데이터베이스 파일을 삭제 ADB를 사용해야합니다.

onUpgrade()

  1. SQLiteOpenHelper 수퍼 생성자를 호출해야합니다.
  2. onUpgrade()방법은 버전 정수가 앱에서 실행중인 현재 버전보다 큰 경우에만 호출됩니다.
  3. 당신이 원하는 경우 onUpgrade()메소드를 호출 할, 당신은 당신의 코드에서 버전 번호를 증가해야합니다.

답변

너무 늦었을 수도 있지만 짧고 달콤한 답변을 공유하고 싶습니다. 같은 문제에 대한 답변 을 확인하십시오 . 확실히 당신을 도울 것입니다. 더 이상 깊은 사양이 없습니다.

테이블 생성 구문에 대해 확신이있는 경우 동일한 테이블에 새 열을 추가 할 때 발생할 수있는 것보다 …

1) 장치에서 제거하고 다시 실행하십시오.

또는

2) 설정-> 앱-> ClearData

또는

3)DATABASE_VERSION “DatabaseHandler”클래스 변경 (새 열을 추가 한 경우 자동으로 업그레이드되는 것보다)

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

또는

4)DATABASE_NAME “DatabaseHandler”클래스의 변경 (같은 문제에 직면했지만 변경하여 성공합니다 DATABASE_NAME.)


답변

확장 할 때 기억해야 할 사항 SQLiteOpenHelper

  1. super(context, DBName, null, DBversion); -생성자의 첫 줄을 호출해야합니다.
  2. 무시 onCreate하고onUpgrade (필요한 경우)
  3. onCreate경우에만 호출됩니다 getWritableDatabase()또는 getReadableDatabase()실행됩니다. 그리고이 때 한 번만 호출됩니다DBName 첫 번째 단계에서 지정된 것을 사용할 수 없을 . onCreate메소드에 테이블 작성 쿼리를 추가 할 수 있습니다.
  4. 새 테이블을 추가 할 때마다 테이블 DBversion에서 쿼리를 변경 하고 수행 onUpgrade하거나 단순히 앱을 제거한 다음 설치하십시오.

답변

onCreate테이블 작성이 필요한 경우 처음으로 가 호출됩니다. SQLiteDatabase에 의해 실행되는 테이블 작성을위한 스크립트를 작성하는 경우이 메소드를 대체해야합니다. execSQL 방법. 최초 배포에서 실행 한 후에는이 메서드가 호출되지 않습니다.

onUpgrade
이 메소드는 데이터베이스 버전이 업그레이드 될 때 호출됩니다. 첫 번째 배포의 경우 데이터베이스 버전이 1이고 두 번째 배포의 경우 테이블에 열을 추가하는 것과 같은 데이터베이스 구조가 변경되었다고 가정합니다. 데이터베이스 버전이 2라고 가정하십시오.


답변

당신은 같은 데이터베이스 및 테이블을 만들 수 있습니다

public class DbHelper extends SQLiteOpenHelper {
private static final String DBNAME = "testdatbase.db";
private static final int VERSION = 1;

public DbHelper(Context context) {
    super(context, DBNAME, null, VERSION);
    // TODO Auto-generated constructor stub
}

@Override
public void onCreate(SQLiteDatabase db) {
    // TODO Auto-generated method stub
    db.execSQL("create table BookDb(id integer primary key autoincrement,BookName text,Author text,IssuedOn text,DueDate text,Fine text,Totalfine text");

}

@Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
    db.execSQL("DROP TABLE IF EXISTS BookDb");
    onCreate(db);
  }
}

참고 : 다른 테이블을 만들거나 열을 추가하거나 그러한 테이블을 추가하지 않으려면 VERSION을 늘리십시오.