Как изменить таблицу и добавить каскадное ограничение onDelete sqlite

Я использую базу данных комнат У меня есть таблица, в которую я забыл добавить onDelete = CASCADE

Предыдущая версия

@Entity(indices = {@Index(value = {"info_id"})}, foreignKeys = @ForeignKey(entity = StudentClass.class, parentColumns = "id", childColumns = "info_id"))

Что я хочу сейчас

@Entity(indices = {@Index(value = {"info_id"})}, foreignKeys = @ForeignKey(entity = StudentClass.class, parentColumns = "id", childColumns = "info_id", onDelete = CASCADE))

Я пытаюсь перенести базу данных

static final Migration MIGRATION_1_2 = new Migration(1, 2) {
        @Override
        public void migrate(SupportSQLiteDatabase database) {
            database.execSQL("What should I do here to add onDelete = CASCADE");
        }
    };
2
0
560
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

Ответ принят как подходящий

Хорошо, наконец, я нашел решение

database.execSQL("CREATE TABLE attendance_temp(attendanceId INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, time INTEGER NOT NULL, student_id INTEGER, student_name TEXT , roll_number INTEGER, image_path TEXT, info_id INTEGER, present INTEGER , CONSTRAINT fk_class_info FOREIGN KEY (info_id) REFERENCES class_info(id) ON DELETE CASCADE)");
database.execSQL("INSERT INTO attendance_temp SELECT * FROM Attendance");
database.execSQL("DROP TABLE Attendance");
database.execSQL("ALTER TABLE attendance_temp RENAME TO Attendance");
database.execSQL("CREATE INDEX index_Attendance_info_id ON Attendance(info_id)");

Также измените схему в классе сущности на

@Entity(indices = {@Index(value = {"info_id"})}, foreignKeys = @ForeignKey(entity = StudentClass.class, parentColumns = "id", childColumns = "info_id", onDelete = CASCADE))

Последовательность важна.

Ого, это, к сожалению, так больно :(

Carson Holzheimer 16.03.2020 03:55

SQLite не полностью поддерживает стандарт SQL ALTER TABLE:

Only the RENAME TABLE, ADD COLUMN, and RENAME COLUMN variants of the ALTER TABLE command are supported. Other kinds of ALTER TABLE operations such as DROP COLUMN, ALTER COLUMN, ADD CONSTRAINT, and so forth are omitted.

Источник

Таким образом, единственный способ добавить ограничение - воссоздать таблицу и скопировать данные из старой таблицы в новую:

// 1. Rename your table
database.execSQL("ALTER TABLE Entity RENAME TO Entity_old")
// 2. Recreate the same entity, but now with the constraint
database.execSQL("""
    CREATE TABLE Entity(
        id INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, 
        parentId INTEGER, 
        someField STRING, 
        CONSTRAINT fk_Entity_entityId_EntityParent_id FOREIGN KEY (entityId) REFERENCES EntityParent(id) ON DELETE CASCADE
    )
""")
// 3. Copy the data from the old table
database.execSQL("INSERT INTO Entity SELECT * FROM Entity_old")
// 4. Delete old table
database.execSQL("DROP TABLE Entity_old")
// 5. Recreate the indices
database.execSQL("CREATE INDEX index_Entity_id ON Entity(id)")

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