[java] SQLite를 사용하는 Android의 외래 키 제약? 계단식 삭제시

두 개의 테이블이 있습니다. 트랙과 웨이 포인트, 트랙에는 여러 웨이 포인트가있을 수 있지만 웨이 포인트는 하나의 트랙에만 할당됩니다.

way points 테이블에는 트랙이 만들어지면 track_ID를 삽입하는 “trackidfk”라는 열이 있지만이 열에 외래 키 제약 조건을 설정하지 않았습니다.

트랙을 삭제할 때 할당 된 웨이 포인트를 삭제하고 싶은데 이것이 가능합니까?. 트리거 사용에 대해 읽었지만 Android에서 지원되지 않는다고 생각합니다.

웨이 포인트 테이블을 생성하려면 :

public void onCreate(SQLiteDatabase db) {
    db.execSQL( "CREATE TABLE " + TABLE_NAME
                + " ("
                + _ID         + " INTEGER PRIMARY KEY AUTOINCREMENT, "
                + LONGITUDE   + " INTEGER,"
                + LATITUDE    + " INTEGER,"
                + TIME        + " INTEGER,"
                + TRACK_ID_FK + " INTEGER"
                + " );"
              );

    ...
}



답변

on delete cascade가있는 외래 키 제약 조건이 지원되지만이를 활성화해야합니다.
난 그냥 내 SQLOpenHelper에 다음을 추가 했는데 트릭을 수행하는 것 같습니다.

@Override
public void onOpen(SQLiteDatabase db) {
    super.onOpen(db);
    if (!db.isReadOnly()) {
        // Enable foreign key constraints
        db.execSQL("PRAGMA foreign_keys=ON;");
    }
}

내 참조 열을 다음과 같이 선언했습니다.

mailbox_id INTEGER REFERENCES mailboxes ON DELETE CASCADE


답변

Android 4.1 (API 16) 이후 SQLiteDatabase 는 다음을 지원합니다.

public void setForeignKeyConstraintsEnabled (boolean enable)


답변

e.shishkin의 게시물이 API 16에서 말했듯이 다음을 사용하여 SqLiteOpenHelper.onConfigure(SqLiteDatabase)메서드 에서 외래 키 제약 조건을 활성화해야 합니다.db.setForeignKeyConstraintsEnabled(boolean)

@Override
public void onConfigure(SQLiteDatabase db){
    db.setForeignKeyConstraintsEnabled(true);
}


답변

더 완전한 답변으로 대답하기에는 너무 오래된 질문이 없습니다.

@Override public void onOpen(SQLiteDatabase db) {
    super.onOpen(db);
    if (!db.isReadOnly()) {
        setForeignKeyConstraintsEnabled(db);
    }
    mOpenHelperCallbacks.onOpen(mContext, db);
}

private void setForeignKeyConstraintsEnabled(SQLiteDatabase db) {
    if (Build.VERSION.SDK_INT < Build.VERSION_CODES.JELLY_BEAN) {
        setForeignKeyConstraintsEnabledPreJellyBean(db);
    } else {
        setForeignKeyConstraintsEnabledPostJellyBean(db);
    }
}

private void setForeignKeyConstraintsEnabledPreJellyBean(SQLiteDatabase db) {
    db.execSQL("PRAGMA foreign_keys=ON;");
}

@TargetApi(Build.VERSION_CODES.JELLY_BEAN)
private void setForeignKeyConstraintsEnabledPostJellyBean(SQLiteDatabase db) {
    db.setForeignKeyConstraintsEnabled(true);
}


답변

@phil이 언급 한 것이 무엇이든 좋습니다. 그러나 데이터베이스 자체에서 사용 가능한 다른 기본 방법을 사용하여 외래 키를 설정할 수 있습니다. 이것이 바로 setForeignKeyConstraintsEnabled (true)입니다.

@Override
public void onOpen(SQLiteDatabase db) {
    super.onOpen(db);
    if (!db.isReadOnly()) {
        // Enable foreign key constraints
        db.execSQL("PRAGMA foreign_keys=ON;");
              //(OR)
        db.setForeignKeyConstraintsEnabled (true)
    }
}

문서의 경우 SQLiteDatabase.setForeignKeyConstraintsEnabled를 참조하십시오.


답변

나는 SQLite가 이것을 즉시 지원한다고 생각하지 않습니다. 내 앱에서 내가하는 일은 :

  1. 거래 생성
  2. 상세 데이터 삭제 (예시의 웨이 포인트)
  3. 마스터 데이터 삭제 (예시의 트랙)
  4. 성공시 트랜잭션 커밋

이렇게하면 모든 데이터가 삭제되거나 전혀 삭제되지 않습니다.


답변

트리거는 Android에서 지원되며 해당 유형의 계단식 삭제는 sqlite에서 지원되지 않습니다. Android에서 트리거를 사용하는 예는 여기 에서 찾을 수 있습니다 . Thorsten이 말한 것처럼 트랜잭션을 사용하는 것은 아마도 트리거만큼 쉽습니다.